我正在尝试使用反射来根据用户输入进行动态函数调用。我正在收集这样的用户输入:
func main() {
for {
reader := bufio.NewReader(os.Stdin)
fmt.Print("> ")
command, _ := reader.ReadString('\n')
runCommandFromString(command)
}
}
命令是这样解析的
func stringCommandParser(cmd string) *Command {
cmdParts := strings.Split(
strings.TrimSpace(cmd),
" ",
)
return &Command{
Name: cmdParts[0],
Args: cmdParts[1:],
}
}
func runCommandFromString(cmd string) {
command := stringCommandParser(cmd)
c := &Commander{}
f := reflect.ValueOf(&c).MethodByName(command.Name)
inputs := []reflect.Value{reflect.ValueOf(command)}
f.Call(inputs)
}
commands.go 文件如下所示
type Command struct {
Name string
Args []string
}
type Commander struct {}
func (c Commander) Hello(cmd Command) {
fmt.Println("Meow", cmd.Args)
}
当我运行该程序时,我得到一个提示,我运行一个名为“Hello”的命令和一个名为“world”的参数。我希望出现“Meow [World]”或类似的东西。像这样:
> Hello world
Meow world
相反,我得到的是一个看起来像这样的 panic :
> Hello world
panic: reflect: call of reflect.Value.Call on zero Value
goroutine 1 [running]:
panic(0x123360, 0xc420014360)
/Users/parris/.gvm/gos/go1.7.4/src/runtime/panic.go:500 +0x1a1
reflect.flag.mustBe(0x0, 0x13)
/Users/parris/.gvm/gos/go1.7.4/src/reflect/value.go:201 +0xae
reflect.Value.Call(0x0, 0x0, 0x0, 0xc420055e00, 0x1, 0x1, 0x0, 0x0, 0x0)
/Users/parris/.gvm/gos/go1.7.4/src/reflect/value.go:300 +0x38
main.runCommandFromString(0xc42000c8a0, 0xc)
/Users/parris/Projects/distro/main/utils.go:26 +0x1a0
main.main()
/Users/parris/Projects/distro/main/main.go:14 +0x149
exit status 2
我该如何解决这个问题?另外,发生了什么事?
最佳答案
您可能想在使用前检查 reflect.ValueOf 返回的内容。
在这种情况下,您将得到一个 nil 值,因为 reflect 无法看到未导出的函数。 hello 以小写字母开头,因此不会导出。
此外,您在这里提出了太多建议,我怀疑您需要执行 reflect.ValueOf(c)。您同时在做和调试太多事情。制作一个简单的工作示例并从那里继续调试。
关于go - panic : reflect: call of reflect. Value.Call 零值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41995110/
我怎样才能完成http://php.net/manual/en/function.call-user-func-array.php在ruby中?所以我可以这样做:classAppdeffoo(a,b)putsa+benddefbarargs=[1,2]App.send(:foo,args)#doesn'tworkApp.send(:foo,args[0],args[1])#doeswork,butdoesnotscaleendend 最佳答案 尝试分解数组App.send(:foo,*args)
在我的系统中,我已经定义了STI。Dog继承自Animal,在animals表中有一个type列,其值为"Dog"。现在我想让SpecialDog继承自dog,只是为了在某些特殊情况下稍微修改一下行为。数据还是一样。我需要通过SpecialDog运行的所有查询,以返回数据库中类型为Dog的值。我的问题是因为我有一个type列,rails将WHERE"animals"."type"IN('SpecialDog')附加到我的查询中,所以我不能获取原始的Dog条目。所以我想要的是以某种方式覆盖rails在通过SpecialDog访问数据库时使用的值,使其表现得像Dog。有没有办法覆盖用于类型
我的rails3.1.6应用程序中有一个自定义访问器方法,它为一个属性分配一个值,即使该值不存在。my_attr属性是一个序列化的哈希,除非为空白,否则应与给定值合并指定了值,在这种情况下,它将当前值设置为空值。(添加了检查以确保值是它们应该的值,但为简洁起见被删除,因为它们不是我的问题的一部分。)我的setter定义为:defmy_attr=(new_val)cur_val=read_attribute(:my_attr)#storecurrentvalue#makesureweareworkingwithahash,andresetvalueifablankvalueisgiven
在Railcasts上,我注意到一个非常有趣的功能“转到符号”窗口。它像Command-T一样工作,但显示当前文件中可用的类和方法。如何在vim中获取它? 最佳答案 尝试:helptags有各种程序和脚本可以生成标记文件。此外,标记文件格式非常简单,因此很容易将sed(1)或类似的脚本组合在一起,无论您使用何种语言,它们都可以生成标记文件。轻松获取标记文件(除了下载生成器之外)的关键在于格式化样式而不是实际解析语法。 关于ruby-on-rails-Textmate'Gotosymbol
编辑:经过进一步测试,问题似乎是站点特定的,理论上应该可以正常工作。本应位于多行的Textarea值正在一行中全部提交。textarea_values="value1\nvalue2"form=page.form_with(:id=>'form_id_here')form['my_textarea']=textarea_valuessubmit=form.button_with(:value=>'Submit')form.click_button(submit)提交的值是value1\nvalue2而不是预期的多行。有没有我可以尝试的另一种添加表单值的方法?
我有一个中等复杂度的Rails应用程序。主Controller(执行应用程序所要做的事情的Controller)只有一个操作方法。(它不是标准的RESTful应用程序;它充当中介,并且对其调用方式有外部限制。)但是,它确实有很多方法和一些过滤器,以及一个不断增长的测试套件。随着时间的推移,结构发生了很大变化,我不再相信为之前编写的测试设置的某些Mocha期望仍然合适。有多个人在开发该应用程序,因此我正在构建一本用于编写功能测试的指南。“当你想在有/没有[那些]副作用的情况下进行测试时,使用[这些]期望和断言”等等。调用树/图在编写此类文档时非常有用。除了过滤器之外,这些甚至可以静态地从
NewRelic向我展示了应用服务器中超过80%的执行时间发生在“MiddlewareActiveRecord::QueryCache#call”中这里是相关测试代码的要点(尽管我在其他API端点上看到了类似的结果)。Gist我正在AWSElasticBeanstalk上的t2.medium实例和t2.smallPostgresRDSDB上运行应用程序服务器,max_connections设置为100。我正在通过loader.io对此进行测试,对100个用户进行测试使用维护客户端负载设置(这意味着每分钟大约6000个请求)。有谁知道为什么QueryCache花费这么多时间?
我有散列的散列(@post),我想在其中保持散列键在数组(@post_csv_order)中的顺序,还想保持关系键=>数组中的值。我不知道数组中@post哈希和key=>value元素的最终数量。我不知道如何在循环中为数组中的所有元素分配散列。一个接一个@post_csv_order[0][0]=>@post_csv_order[0][1]效果很好。#require'rubygems'require'pp'@post={}forum_id=123#onlysamplevalues....tomakethissamplescriptworkpost_title="Testpost"@po
我现在调用第三方网络服务作为我的应用程序的一部分。我正在使用RestClientgem来执行此操作。有大量工具可以用来做同样的事情,所以这应该无关紧要。我很好奇的是有足够好的测试,没有什么太花哨的,我可以在其中模拟当第三方Web服务出于任何原因不可用时我的应用程序如何响应。无论是我超出了速率限制还是由于网络延迟/并发症而超时,我只想能够获取HTTP状态代码之类的东西并测试我的应用程序在该事件中执行的操作。使用Test::Unit执行此操作的最佳方法是什么?现在,对第三方服务的调用封装在我的一个Controller中。我有一个简单的模块,其中包含一些用于远程服务不同端点的包装器方法。我只
为什么我可以这样改变“self”:self.map!{|x|x*2}或者这样:self.replace(self.map{|x|x*2})但不是这样:self=self.map{|x|x*2}为什么Ruby不允许我更改“self”变量指向的对象,但允许我更改对象的属性? 最佳答案 不是答案,只是一个线索。a=[1,2]=>[1,2]a.object_id=>2938a.map!{|x|x*2}=>[2,4]a.object_id#differentdatabutstillthesameobject=>2938a.replace(a.