tao4free
tao4free

Reputation: 33

Why can not use Pointer() method when reflect.Value is passed to an interface in golang?

I am writing a unit test to check equality of struct that contains func.

Here are my test code. Go Palyround

When comparing, I used a func named GetFunctionName to get function's name for going.

func GetFunctionName(i interface{}) string {
    fmt.Printf("type in GetFunctionName: %v\n", reflect.TypeOf(reflect.ValueOf(i)))
    return runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name()
}

Also a compare function was made.

func SelectCompareStruct(got interface{}, want interface{}) {
    rvGot := reflect.ValueOf(got)
    rtGot := rvGot.Type()
    rvWant := reflect.ValueOf(want)
    rtWant := rvWant.Type()

    for i := 0; i < rtGot.NumField(); i++ {
        fieldGot := rtGot.Field(i)
        fieldWant := rtWant.Field(i)

        valueGot := rvGot.FieldByName(fieldGot.Name)
        valueWant := rvWant.FieldByName(fieldWant.Name)
        fmt.Printf("type in SelectCompareStruct: %v\n", reflect.TypeOf(reflect.ValueOf(valueGot)))

        // Works
        gotFuncNameInner := runtime.FuncForPC(valueGot.Pointer()).Name()
        wantFuncNameInner := runtime.FuncForPC(valueWant.Pointer()).Name()
        fmt.Printf("gotFuncNameInner:\n\t\t\t%v\nwantFuncNameInner:\n\t\t\t%v\n", gotFuncNameInner, wantFuncNameInner)

        // Does not work
        gotFuncName := GetFunctionName(valueGot)
        wantFuncName := GetFunctionName(valueWant)
        fmt.Printf("gotFuncName:\n\t%v\n wantFuncName:\n\t%v\n", gotFuncName, wantFuncName)
    }
}

You can see, when I write directly to get function's name, it works. However, it does not work when using a func instead. Although, both of which type that apply Pointer() method are reflect.Value type.

Yes, I can change input type of GetFunctionName to reflect.Value for working. That's not good for other use cases. I want to make a function for getting name for versatility. It will be beautiful to make input type interface{}.

Anyone have any idea why? And how to fix it?

Upvotes: 0

Views: 675

Answers (1)

user13631587
user13631587

Reputation:

The problem is that you are calling reflect.Value on a reflect.Value. Fix by removing the extra call to reflect.Value.

func GetFunctionName(v reflect.Value) string {
    fmt.Printf("type in GetFunctionName: %v\n", v.Type())
    return runtime.FuncForPC(v.Pointer()).Name()
}

Run it on the playground.

Upvotes: 1

Related Questions