猿问

指针问题。

不知何故,我在对象的 for 循环中附加了一个指向列表而不是对象的指针,因此最后整个切片由同一对象多次组成。我只是不知道如何解决这个问题。


漫漫长路


我仍然很难在 go 中找出指针。我昨天发布了一个问题并得到了一些帮助,但现在我在同一段代码中遇到了一个略有不同的问题。


我有工作gocql,并cqlr去包,试图咬一小对象映射为我的卡桑德拉查询。本质上,我遇到的问题是我将似乎是指向对象的指针而不是 obj 的新实例附加到数组。我该如何解决?我试过在前面添加&和*,value但这似乎不起作用。我该如何解决这些问题?&根据他们的文档,绑定函数需要一个。


代码


type Query struct {

    query       string

    values      interface{}

    attempts    int

    maxAttempts int

    structType  reflect.Type

}


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).Interface()

    for bindQuery.Scan(value) {

        fmt.Println(value)

        results = append(results, value)

    }

    return

}

文档要求var value type然后绑定你会通过&value。我引用了下面的文档。


var t Tweet

var s []Tweet

for b.Scan(&t) {

    // Application specific code goes here

    append(s, t)

}

问题是我不能直接var value query.structType定义它的类型然后将它的引用传递给bindQuery.Scan().


印什么


&{result1 x86_64 24 3.2.0-74-generic Linux}

&{result2 x86_64 24 3.19.0-25-generic Linux}

&{result3 x86_64 4 3.13.0-48-generic Linux}

&{result4 x86_64 2 3.13.0-62-generic Linux}

&{result5 x86_64 4 3.13.0-48-generic Linux}

切片中有什么


剧透,result5一遍又一遍地重复。我知道我只是将指向同一对象的指针附加到列表中,并且每次循环迭代对象都会更改,并且会将切片中的所有结果更改为该新对象。我只是不知道如何解决它。


[{"hostname":"result5","machine":"x86_64","num_cpus":4,"release":"3.13.0-48-generic","sysname":"Linux"},{"hostname":"result5","machine":"x86_64","num_cpus":4,"release":"3.13.0-48-generic","sysname":"Linux"},{"hostname":"result5","machine":"x86_64","num_cpus":4,"release":"3.13.0-48-generic","sysname":"Linux"},{"hostname":"result5","machine":"x86_64","num_cpus":4,"release":"3.13.0-48-generic","sysname":"Linux"},{"hostname":"result5","machine":"x86_64","num_cpus":4,"release":"3.13.0-48-generic","sysname":"Linux"}]


慕容森
浏览 145回答 1
1回答

HUH函数

好吧,我至少可以告诉你你在做什么。bindQuery需要一个指针。它更改存储在地址中的值。你基本上做的是这样的:package mainimport "fmt"func main() {&nbsp; &nbsp; var q int&nbsp; &nbsp; myInts := make([]*int, 0, 5)&nbsp; &nbsp; for i := 0; i < 5; i++ {&nbsp; &nbsp; &nbsp; &nbsp; q = i&nbsp; &nbsp; &nbsp; &nbsp; fmt.Printf("%d ", q)&nbsp; &nbsp; &nbsp; &nbsp; myInts = append(myInts, &q)&nbsp; &nbsp; }&nbsp; &nbsp; fmt.Printf("\n")&nbsp; &nbsp; for _, value := range myInts {&nbsp; &nbsp; &nbsp; &nbsp; fmt.Printf("%d ", *value)&nbsp; &nbsp; }&nbsp; &nbsp; fmt.Printf("\n")&nbsp; &nbsp; fmt.Println(myInts)}正如您可能猜到的那样,它为您提供了以下信息:0 1 2 3 4&nbsp;4 4 4 4 4&nbsp;[0x104382e0 0x104382e0 0x104382e0 0x104382e0 0x104382e0]事情变得有点混乱reflect。您可以将您的类型作为接口,但仅此而已(除非您想使用unsafe)。简单来说,接口包含一个指向底层原始类型(以及其他一些东西)的指针。所以在你的函数中你传递了一个指针(和其他一些东西)。然后你要附加指针。只是具体化并键入 switch 您的界面可能会很好。我假设你知道它可能是什么类型。在这种情况下,您必须按照以下方式进行操作:package mainimport (&nbsp; &nbsp; "fmt"&nbsp; &nbsp; "reflect")type foo struct {&nbsp; &nbsp; fooval string}type bar struct {&nbsp; &nbsp; barval string}func main() {&nbsp; &nbsp; f1 := foo{"hi"}&nbsp; &nbsp; f2 := &foo{"hi"}&nbsp; &nbsp; b1 := bar{"bye"}&nbsp; &nbsp; b2 := &bar{"bye"}&nbsp; &nbsp; doSomething(f1)&nbsp; &nbsp; doSomething(f2)&nbsp; &nbsp; doSomething(b1)&nbsp; &nbsp; doSomething(b2)}func doSomething(i interface{}) {&nbsp; &nbsp; n := reflect.TypeOf(i)&nbsp; &nbsp; // get a new one&nbsp; &nbsp; newn := reflect.New(n).Interface()&nbsp; &nbsp; // find out what we got and handle each case&nbsp; &nbsp; switch t := newn.(type) {&nbsp; &nbsp; case **foo:&nbsp; &nbsp; &nbsp; &nbsp; *t = &foo{"hi!"}&nbsp; &nbsp; &nbsp; &nbsp; fmt.Printf("It was a **foo, here is the address %p and here is the value %v\n", *t, **t)&nbsp; &nbsp; case **bar:&nbsp; &nbsp; &nbsp; &nbsp; *t = &bar{"bye :("}&nbsp; &nbsp; &nbsp; &nbsp; fmt.Printf("It was a **bar, here is the address %p and here is the value %v\n", *t, **t)&nbsp; &nbsp; case *foo:&nbsp; &nbsp; &nbsp; &nbsp; t = &foo{"hey!"}&nbsp; &nbsp; &nbsp; &nbsp; fmt.Printf("It was a *foo, here is the address %p and here is the value %v\n", t, *t)&nbsp; &nbsp; case *bar:&nbsp; &nbsp; &nbsp; &nbsp; t = &bar{"ahh!"}&nbsp; &nbsp; &nbsp; &nbsp; fmt.Printf("It was a *bar, here is the address %p and here is the value %v\n", t, *t)&nbsp; &nbsp; default:&nbsp; &nbsp; &nbsp; &nbsp; panic("AHHHH")&nbsp; &nbsp; }}您也可以继续value = reflect.New(query.structType).Interface()在循环内部调用,每次都会为您提供新的接口。每次追加后重新分配值。上次通过循环会使一个额外的虽然..
随时随地看视频慕课网APP

相关分类

Go
我要回答