gpt4 book ai didi

reflection - Go: reflect : 调用输入参数太少

转载 作者:数据小太阳 更新时间:2023-10-29 03:33:18 28 4
gpt4 key购买 nike

我一直坚持使用反射库的问题。由于很多推荐,我决定使用它,但我只是在学习,有些部分并不是很容易..

我有这部分代码:

 func countDataByName(sourceName string, statData interface{}, filters Filter, chartName string) []ChartElement {
...
//step 1 - filter
filteredData := reflect.ValueOf(statData).MethodByName("FilterData").Call([]reflect.Value{})

//step 2 - cluster
// clusterData := reflect.ValueOf(filteredData).MethodByName("clusterData").Call([]reflect.Value{})

//step 3 - count
// countedData := reflect.ValueOf(clusterData).MethodByName(chartName).Call([]reflect.Value{})

fmt.Println("Never prints to anywhere", filteredData)

...
return filterData
}

如果我执行这样的方法,我会得到错误:reflect: Call with too few input arguments。但是,如果我在 reflect.ValueOf(&statData) 上更改 reflect.ValueOf(statData),则错误是 reflect: call of reflect.Value.Call on zero Value

statData 带有 2 种类型之一,在这种类型之前,我有结构和方法,如下所示:

type NoaggModel struct {
Date string
Hour int
Id_user int
Id_line int
Id_region int
Id_tree_devision int
N_inb int
N_inb_d int
T_ring int
T_inb int
T_inb_d int
T_hold int
T_acw int
T_acw_d int
T_wait int
}

func (ng *NoaggModel) FilterData( data NoaggModel) {
fmt.Println("FilterData")
fmt.Println("data : ", data)
}

这个 Println 也不起作用。上面的代码崩溃,并且没有触发方法。我的错误在哪里?

更新 1:

发现如果我在我想调用的函数中删除参数 data,它会很好地调用。但!我有 statData 作为结构的 1 行,所以类型是 NoaggModel。在 FilterData 方法中,我将这 1 行作为 ng 获取。但我需要将其更改为 []NoaggModel。在这种情况下如何调用 reflect 以及如何将参数传递给过滤器函数?

更新 2:我修改了几个部分:

func (ng *NoaggModel) FilterData(filter interface{}, data NoaggModel) {
fmt.Println("data : ",ng)
}

在这里,如何将正确的类型传递给 filter,如果它在 revel Controller 中设置,并且方法在模型中。或者我应该在每个模型中设置类型并在 Controller 中调用它?

我在 Controller 中写道:

//step 1 - filter
in := make([]reflect.Value, 2)

in[0] = reflect.ValueOf(filters)
in[1] = reflect.ValueOf(statData)

filteredData := reflect.ValueOf(statData).MethodByName("FilterData").Call(in)

StatData 是 NoaggModel 类型的一行,但我收到错误:

 reflect: Call using *models.NoaggModel as type models.NoaggModel 

类型也由上面代码中的 reflect 设置,如下所示:

    ...
var sourceTypes = map[string]reflect.Type{
"noagg": reflect.TypeOf(models.NoaggModel{}),
"oracle": reflect.TypeOf(models.OracleModel{}),
}
deserializedData = reflect.New(sourceTypes[sourceName]).Interface()
...
// deserialised becomes statData

最佳答案

反射(reflection)并不容易。并且应尽可能避免。

我承认我确实建议使用 reflect 来基于映射动态创建类型实例,当您不知道可能需要处理哪些类型时,这非常有用。但在您的情况下,您应该考虑使用接口(interface)。

虽然我真的不知道您想要实现什么,但我建议您首先创建一个所有模型都需要实现的接口(interface)(修改它以满足您的需求):

type Model interface {
FilterData(interface{})
}

NoaggModelOracleModel 将通过定义如下类似方法来实现上述接口(interface):

func (ng *NoaggModel) FilterData(filter interface{}) {
fmt.Printf("data: %#v, filter: %#v\n", ng, filter)
}

然后,将 deserializedData(和 statData)更改为接口(interface)类型 Model 而不是 interface{}。由于您只有两种类型,因此您可以通过切换来避免使用反射:

...
var deserializedData Model

switch sourceName {
case "noagg":
deserializedData = new(models.NoaggModel)
case "oracle":
deserializedData = new(models.OracleModel)
}
...
// Marshal the values into deserializedData which now holds an instance of the desired type
...
deserializedData.FilterData("Replace this string with your filter")

而且无需导入 reflect 即可完成!

关于reflection - Go: reflect : 调用输入参数太少,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35429132/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com