我一直坚持使用反射库的问题。由于很多推荐,我决定使用它,但我只是在学习,有些部分并不是很容易..
我有这部分代码:
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{})
}
NoaggModel 和 OracleModel 将通过定义如下类似方法来实现上述接口(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/
exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby中使用两个参数异步运行exe吗?我已经尝试过ruby命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何rubygems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除
我有一些Ruby代码,如下所示:Something.createdo|x|x.foo=barend我想编写一个测试,它使用double代替block参数x,这样我就可以调用:x_double.should_receive(:foo).with("whatever").这可能吗? 最佳答案 specify'something'dox=doublex.should_receive(:foo=).with("whatever")Something.should_receive(:create).and_yield(x)#callthere
我正在为一个项目制作一个简单的shell,我希望像在Bash中一样解析参数字符串。foobar"helloworld"fooz应该变成:["foo","bar","helloworld","fooz"]等等。到目前为止,我一直在使用CSV::parse_line,将列分隔符设置为""和.compact输出。问题是我现在必须选择是要支持单引号还是双引号。CSV不支持超过一个分隔符。Python有一个名为shlex的模块:>>>shlex.split("Test'helloworld'foo")['Test','helloworld','foo']>>>shlex.split('Test"
我不确定传递给方法的对象的类型是否正确。我可能会将一个字符串传递给一个只能处理整数的函数。某种运行时保证怎么样?我看不到比以下更好的选择:defsomeFixNumMangler(input)raise"wrongtype:integerrequired"unlessinput.class==FixNumother_stuffend有更好的选择吗? 最佳答案 使用Kernel#Integer在使用之前转换输入的方法。当无法以任何合理的方式将输入转换为整数时,它将引发ArgumentError。defmy_method(number)
两者都可以defsetup(options={})options.reverse_merge:size=>25,:velocity=>10end和defsetup(options={}){:size=>25,:velocity=>10}.merge(options)end在方法的参数中分配默认值。问题是:哪个更好?您更愿意使用哪一个?在性能、代码可读性或其他方面有什么不同吗?编辑:我无意中添加了bang(!)...并不是要询问nobang方法与bang方法之间的区别 最佳答案 我倾向于使用reverse_merge方法:option
我正在尝试编写一个将文件上传到AWS并公开该文件的Ruby脚本。我做了以下事情:s3=Aws::S3::Resource.new(credentials:Aws::Credentials.new(KEY,SECRET),region:'us-west-2')obj=s3.bucket('stg-db').object('key')obj.upload_file(filename)这似乎工作正常,除了该文件不是公开可用的,而且我无法获得它的公共(public)URL。但是当我登录到S3时,我可以正常查看我的文件。为了使其公开可用,我将最后一行更改为obj.upload_file(file
我有一个只接受一个参数的方法:defmy_method(number)end如果使用number调用方法,我该如何引发错误??通常,我如何定义方法参数的条件?比如我想在调用的时候报错:my_method(1) 最佳答案 您可以添加guard在函数的开头,如果参数无效则引发异常。例如:defmy_method(number)failArgumentError,"Inputshouldbegreaterthanorequalto2"ifnumbereputse.messageend#=>Inputshouldbegreaterthano
如何在ruby中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL
我没有找到太多关于如何执行此操作的信息,尽管有很多关于如何使用像这样的redirect_to将参数传递给重定向的建议:action=>'something',:controller=>'something'在我的应用程序中,我在路由文件中有以下内容match'profile'=>'User#show'我的表演Action是这样的defshow@user=User.find(params[:user])@title=@user.first_nameend重定向发生在同一个用户Controller中,就像这样defregister@title="Registration"@user=Use
我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www