Home > other >  Why does MethodByName().Call() return "[<float64 Value>]"?
Why does MethodByName().Call() return "[<float64 Value>]"?

Time:10-24

I have the following interface

import (
    "fmt"
    "reflect"
)

type geometry interface {
    Area() float64
    Perimeter() float64
}

func prettyPrint(geometry geometry) {
    geometryType := reflect.TypeOf(geometry)
    fmt.Println(geometryType.Name())
    fmt.Printf("\t% v\n", geometry)

    for i := 0; i < geometryType.NumMethod(); i   {
        method := geometryType.Method(i)
        fmt.Println(method.Name)
        fmt.Println(reflect.ValueOf(geometry).MethodByName(method.Name).Call(nil))
    }
}

When calling prettyPrint using a type which implements geometry:

func main() {
    circle := circle{radius: 5}
    prettyPrint(circle)
}

This is the output

circle
        {radius:5}
Area
[<float64 Value>]
Perimeter
[<float64 Value>]

I don't quite understand the reflect.Call() method, or why its printing out each value as [<float64 Value>] - I am trying to get the resulting output from calling the func on the passed in geometry type

I've tried passing in []reflect.Value{} instead of nil as suggested in various places online, but it gives the same results as above

Can anyone shed some light on what exactly is going on here?


I also tried this Invoke method from elsewhere on SO

func Invoke(any interface{}, name string, args ...interface{}) {
    inputs := make([]reflect.Value, len(args))
    for i, _ := range args {
        inputs[i] = reflect.ValueOf(args[i])
    }
    fmt.Println(reflect.ValueOf(any).MethodByName(name).Call(inputs))
}

It gives the same results..

Invoke(circle{}, "Area")

outputs

[<float64 Value>]

CodePudding user response:

The .Call returns a slice of values, returned by the method called. Both of your methods on that interface return a float64, so this is exactly what you see in the print - a slice containing a single float64 value. This is due to the fact the the method can be returning more than a single value.

Try doing

fmt.Println(reflect.ValueOf(geometry).MethodByName(method.Name).Call(nil)[0])

and everything will start to make sense.

  • Related