草庐IT

pointers - 需要帮助通过 'reflect: NumField of non-struct type'

coder 2023-06-26 原文

我正在尝试构建一个查询结构,该结构将表示进出我们的 Cassandra 数据库的数据。

问题是,我正在尝试将类型作为我在结构中的字段之一,以便稍后重建它。我觉得我真的很接近,但这给了我一些问题。尝试执行此操作时,我遇到了一个看起来非常讨厌的错误:

2015/11/17 15:42:22 http: panic serving 127.0.0.1:57962: reflect: NumField of non-struct type
goroutine 34 [running]:
net/http.(*conn).serve.func1(0xc820184000, 0x7f36d7459b00, 0xc820180008)
    /usr/lib/go/src/net/http/server.go:1287 +0xb5
reflect.(*rtype).NumField(0x790820, 0xc8200b9a60)
    /usr/lib/go/src/reflect/type.go:660 +0x7b
github.com/relops/cqlr.(*Binding).compile(0xc82004f6f0, 0x77ab60, 0xc8200b9a60, 0x16, 0xc820194140, 0x5, 0x5, 0x0, 0x0)
    /home/jared/dev/go-pp/src/github.com/relops/cqlr/cqlr.go:160 +0xf8
github.com/relops/cqlr.(*Binding).Scan(0xc82004f6f0, 0x77ab60, 0xc8200b9a60, 0x825280)
    /home/jared/dev/go-pp/src/github.com/relops/cqlr/cqlr.go:99 +0x199
main/cassandra/query.Query.RetryingQuery(0x9325e0, 0x19, 0x0, 0x0, 0x0, 0x0, 0x7f36d74580a8, 0x87b120, 0x0, 0x0, ...)
    /home/jared/dev/go-pp/src/main/cassandra/query/query.go:39 +0x39e
main.ViewHosts(0x7f36d7459f88, 0xc8200e73f0, 0xc82018e000)
    /home/jared/dev/go-pp/src/main/handlers.go:86 +0x1f3
net/http.HandlerFunc.ServeHTTP(0x9a03b0, 0x7f36d7459f88, 0xc8200e73f0, 0xc82018e000)
    /usr/lib/go/src/net/http/server.go:1422 +0x3a
main/utils.Logger.func1(0x7f36d7459f88, 0xc8200e73f0, 0xc82018e000)
    /home/jared/dev/go-pp/src/main/utils/logger.go:32 +0x9c
net/http.HandlerFunc.ServeHTTP(0xc820109200, 0x7f36d7459f88, 0xc8200e73f0, 0xc82018e000)
    /usr/lib/go/src/net/http/server.go:1422 +0x3a
github.com/gorilla/mux.(*Router).ServeHTTP(0xc82001aa00, 0x7f36d7459f88, 0xc8200e73f0, 0xc82018e000)
    /home/jared/dev/go-pp/src/github.com/gorilla/mux/mux.go:100 +0x29e
net/http.serverHandler.ServeHTTP(0xc82016b1a0, 0x7f36d7459f88, 0xc8200e73f0, 0xc82018e000)
    /usr/lib/go/src/net/http/server.go:1862 +0x19e
net/http.(*conn).serve(0xc820184000)
    /usr/lib/go/src/net/http/server.go:1361 +0xbee
created by net/http.(*Server).Serve
    /usr/lib/go/src/net/http/server.go:1910 +0x3f6

这是代码

type Query struct {
    query       string
    values      interface{}
    attempts    int
    maxAttempts int
    structType  reflect.Type
}

func NewQuery(query string, t reflect.Type) (q Query) {
    q.query = query
    q.structType = t
    return
}

func (query Query) RetryingQuery() (results []interface{}) {
    var q *gocql.Query
    if query.values != nil {
        q = c.Session.Query(query.query, query.values)
    } else {
        q = c.Session.Query(query.query)
    }

    bindQuery := cqlr.BindQuery(q)

    value := reflect.New(query.structType).Pointer()
    for bindQuery.Scan(&value) {
        results = append(results, value)
    }
    return
}


// setting up and calling the query here (in another file)
var host cmodels.Host
query := query.NewQuery("SELECT * FROM server.host", reflect.TypeOf(host))
queryResults := query.RetryingQuery()

然而,通过对代码稍作修改,我克服了错误,但我得到了一个奇怪的结果。

func (query Query) RetryingQuery() (results []interface{}) {
    var q *gocql.Query
    if query.values != nil {
        q = c.Session.Query(query.query, query.values)
    } else {
        q = c.Session.Query(query.query)
    }

    bindQuery := cqlr.BindQuery(q)
    value := reflect.New(query.structType)
    for bindQuery.Scan(&value) {
        results = append(results, value)
    }
    return
}

上面的代码给了我:

[{"flag":22},{"flag":22},{"flag":22},{"flag":22},{"flag":22},...]

最佳答案

更改自:

value := reflect.New(query.structType)
for bindQuery.Scan(&value) {

到:

value := reflect.New(query.structType).Interface()
for bindQuery.Scan(value) {

参见 here一个完整的工作示例(粘贴在下面):

package main

import "reflect"

func Scan(d interface{}) {
    v := reflect.ValueOf(d)
    i := reflect.Indirect(v)
    s := i.Type()
    println(s.NumField()) // will print out 0, if you change Host to have 1 field, it prints out 1
}

func query(t reflect.Type) {
    value := reflect.New(t).Interface()
    Scan(value)
}

type Host struct{}
// type Host struct{int} // comment above line, uncomment this one, and println above will print 1

func main() {
    var h Host
    query(reflect.TypeOf(h))
}

这会模拟您的代码以及 clqr 库的作用(请参阅 https://github.com/relops/cqlr/blob/master/cqlr.go#L85-L99https://github.com/relops/cqlr/blob/master/cqlr.go#L154-L160)。您基本上需要 s := i.Type() 成为 TypeOf 您的 Host 结构,所以如果您从 clqr 代码向后工作正在做,您可以推断出您需要传递给 Scan 调用的内容。鉴于您的输入是 reflect.Type,您可以推断出如何从该 Type 获取正确类型的对象以传递给 Scan

关于pointers - 需要帮助通过 'reflect: NumField of non-struct type',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33768554/

有关pointers - 需要帮助通过 'reflect: NumField of non-struct type'的更多相关文章

  1. ruby-on-rails - rails : "missing partial" when calling 'render' in RSpec test - 2

    我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou

  2. ruby - 我需要将 Bundler 本身添加到 Gemfile 中吗? - 2

    当我使用Bundler时,是否需要在我的Gemfile中将其列为依赖项?毕竟,我的代码中有些地方需要它。例如,当我进行Bundler设置时:require"bundler/setup" 最佳答案 没有。您可以尝试,但首先您必须用鞋带将自己抬离地面。 关于ruby-我需要将Bundler本身添加到Gemfile中吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/4758609/

  3. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  4. ruby - 通过 rvm 升级 ruby​​gems 的问题 - 2

    尝试通过RVM将RubyGems升级到版本1.8.10并出现此错误:$rvmrubygemslatestRemovingoldRubygemsfiles...Installingrubygems-1.8.10forruby-1.9.2-p180...ERROR:Errorrunning'GEM_PATH="/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/ruby-1.9.2-p180@global:/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/rub

  5. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

    我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

  6. ruby - 在 jRuby 中使用 'fork' 生成进程的替代方案? - 2

    在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',

  7. ruby - 通过 erb 模板输出 ruby​​ 数组 - 2

    我正在使用puppet为ruby​​程序提供一组常量。我需要提供一组主机名,我的程序将对其进行迭代。在我之前使用的bash脚本中,我只是将它作为一个puppet变量hosts=>"host1,host2"我将其提供给bash脚本作为HOSTS=显然这对ruby​​不太适用——我需要它的格式hosts=["host1","host2"]自从phosts和putsmy_array.inspect提供输出["host1","host2"]我希望使用其中之一。不幸的是,我终其一生都无法弄清楚如何让它发挥作用。我尝试了以下各项:我发现某处他们指出我需要在函数调用前放置“function_”……这

  8. ruby - 主要 :Object when running build from sublime 的未定义方法 `require_relative' - 2

    我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby​​1.9+ 关于ruby-主要:Objectwhenrun

  9. ruby - 无法让 RSpec 工作—— 'require' : cannot load such file - 2

    我花了三天的时间用头撞墙,试图弄清楚为什么简单的“rake”不能通过我的规范文件。如果您遇到这种情况:任何文件夹路径中都不要有空格!。严重地。事实上,从现在开始,您命名的任何内容都没有空格。这是我的控制台输出:(在/Users/*****/Desktop/LearningRuby/learn_ruby)$rake/Users/*******/Desktop/LearningRuby/learn_ruby/00_hello/hello_spec.rb:116:in`require':cannotloadsuchfile--hello(LoadError) 最佳

  10. ruby - rspec 需要 .rspec 文件中的 spec_helper - 2

    我注意到像bundler这样的项目在每个specfile中执行requirespec_helper我还注意到rspec使用选项--require,它允许您在引导rspec时要求一个文件。您还可以将其添加到.rspec文件中,因此只要您运行不带参数的rspec就会添加它。使用上述方法有什么缺点可以解释为什么像bundler这样的项目选择在每个规范文件中都需要spec_helper吗? 最佳答案 我不在Bundler上工作,所以我不能直接谈论他们的做法。并非所有项目都checkin.rspec文件。原因是这个文件,通常按照当前的惯例,只

随机推荐