猿问

需要帮助克服“反射:非结构类型的 NumField”

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


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


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



繁华开满天机
浏览 166回答 1
1回答

紫衣仙女

更改自:value := reflect.New(query.structType)for bindQuery.Scan(&value) {到:value := reflect.New(query.structType).Interface()for bindQuery.Scan(value) {有关完整的工作示例,请参见此处(粘贴在下面):package mainimport "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 1func main() {    var h Host    query(reflect.TypeOf(h))}这模拟了您的代码以及 clqr 库的作用(请参阅https://github.com/relops/cqlr/blob/master/cqlr.go#L85-L99和https://github.com/relops/cqlr/ blob/master/cqlr.go#L154-L160)。你基本上需要s := i.Type()成为TypeOf你的Host结构,所以如果你从 clqr 代码所做的事情向后工作,你可以推断出你需要传递给Scan调用的内容。并且鉴于您拥有的输入是 a reflect.Type,您可以推断出如何从中获得Type要传递到的正确类型的对象Scan。
随时随地看视频慕课网APP

相关分类

Go
我要回答