Pointers 需要帮助通过';反射:非结构类型的NumField';
我正在尝试构建一个查询结构,它将表示与Cassandra数据库之间的数据 问题是,我试图将类型作为结构中的一个字段,以便以后可以重建它。我觉得我真的很接近,但这给了我一些问题。我在尝试这样做时遇到了一个非常严重的错误:Pointers 需要帮助通过';反射:非结构类型的NumField';,pointers,struct,go,Pointers,Struct,Go,我正在尝试构建一个查询结构,它将表示与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
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) {
致:
有关完整的工作示例(粘贴在下面),请参见:
这将模拟您的代码以及clqr库的功能(请参见和)。基本上,您需要
s:=i.Type()
作为Type的Host
struct,因此,如果您从clqr代码正在执行的操作进行反向工作,您可以推断需要传递给Scan
调用的内容。假设您的输入是一个reflect.Type
,您可以推断如何从该Type
获取要传递到Scan
的正确类型的对象,您的意思是让用于bindQuery.Scan(&value)
还是如果是bindQuery.Scan(&value)
?这并不是引起您恐慌的原因,只是澄清一下。应该是因为,bindQuery是一个切片,我们希望遍历它们并将它们附加到列表中。这就是我遇到问题的地方,获取正确的值bindQuery.Scan
似乎返回bool:我不认为我关心bool,只是想在bindQuery
上进行迭代,不管怎样,都可以查看最近的编辑。哦,我明白了,它将继续进行扫描,直到返回false。
value := reflect.New(query.structType).Interface()
for bindQuery.Scan(value) {
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))
}