为什么Go反射NumField()仅在类型上可用?

I have the following Go code (play.golang.org):

package main

import (
    "reflect"
    "fmt"
)

type User struct {
    name string
    email string
}

func main() {   
    uS := User{}
    uSt := reflect.TypeOf(uS)   

    fmt.Println( uSt )
    fmt.Println( uSt.NumField() )
    // fmt.Println( uS.NumField() ) // this doesn't work, why?

}

I'm just curious here. Why we need to get the type of the struct first before calling NumField()?

Why can't we just call it on the struct itself i.e. uS.NumField()?

From docs:

type Value struct {
        // contains filtered or unexported fields
}

func (v Value) NumField() int

I'm not quite getting what is Value really means here. I do really appreciate concise explanation and examples.

NumField() is a function of reflected structs and can be applied on any struct once you have reflected it.

It is NOT a function of User. You did not create any functions for User, so I did to try to clarify

https://play.golang.org/p/c8oGa_56YfE

TypeOf returns the reflection Type that represents the dynamic type of i. If i is a nil interface value, TypeOf returns nil.

From above statement it is clear that TypeOf returns reflection Type

func TypeOf(i interface{}) Type // return reflection type

Reflection type is defined in Golang as

Type is the representation of a Go type. Type values are comparable, such as with the == operator, so they can be used as map keys.

Value is the reflection interface to a Go value which you are using for Numfield method as receiver. As @Flimzy described that for any other reflection method also you need to use reflection value.

In your code:

uS := User{}
uSt := reflect.TypeOf(uS)

First value us is assigned with User type struct. While second value uSt is assigned as reflection Type from the returned value of reflect.TypeOf. Check the type of each variable:

package main

import (
    "reflect"
    "fmt"
)

type User struct {}

func main() {   
    uS := User{}
    uSt := reflect.TypeOf(uS)
    fmt.Printf("%T
", uS) // Print the type of uS
    fmt.Printf("%T
", uSt)
}

Ouput

main.User
*reflect.rtype

Playground Example

For more information on how reflection works. Go through Laws of Reflection