【问题标题】:Why does MethodByName().Call() return "[<float64 Value>]"?为什么 MethodByName().Call() 返回“[<float64 Value>]”?
【发布时间】:2021-12-10 01:28:07
【问题描述】:

我有如下界面

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))
    }
}

当使用实现geometry的类型调用prettyPrint时:

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

这是输出

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

我不太明白reflect.Call() 方法,或者为什么它将每个值打印为[&lt;float64 Value&gt;] - 我试图通过调用传入的geometry 类型的函数来获得结果输出

我尝试过传递[]reflect.Value{} 而不是nil,正如网上各个地方所建议的那样,但它给出的结果与上述相同

谁能解释一下这里到底发生了什么?


我也在 SO 的其他地方尝试了这种 Invoke 方法

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))
}

它给出了相同的结果..

Invoke(circle{}, "Area")

输出

[<float64 Value>]

【问题讨论】:

    标签: go reflection


    【解决方案1】:

    .Call 返回一个值切片,由调用的方法返回。您在该接口上的两个方法都返回一个 float64,所以这正是您在打印中看到的 - 一个包含单个 float64 值的切片。这是因为该方法可以返回多个值。

    尝试做

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

    一切都会开始变得有意义。

    【讨论】:

      猜你喜欢
      • 2018-02-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多