为了账号安全,请及时绑定邮箱和手机立即绑定

指针问题。

指针问题。

Go
慕容森 2021-11-22 18:10:34
不知何故,我在对象的 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 Tweetvar s []Tweetfor 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"}]
查看完整描述

1 回答

?
HUH函数

TA贡献1836条经验 获得超4个赞

好吧,我至少可以告诉你你在做什么。bindQuery需要一个指针。它更改存储在地址中的值。


你基本上做的是这样的:


package main


import "fmt"


func main() {

    var q int

    myInts := make([]*int, 0, 5)

    for i := 0; i < 5; i++ {

        q = i

        fmt.Printf("%d ", q)

        myInts = append(myInts, &q)

    }

    fmt.Printf("\n")

    for _, value := range myInts {

        fmt.Printf("%d ", *value)

    }

    fmt.Printf("\n")

    fmt.Println(myInts)

}

正如您可能猜到的那样,它为您提供了以下信息:


0 1 2 3 4 

4 4 4 4 4 

[0x104382e0 0x104382e0 0x104382e0 0x104382e0 0x104382e0]

事情变得有点混乱reflect。您可以将您的类型作为接口,但仅此而已(除非您想使用unsafe)。简单来说,接口包含一个指向底层原始类型(以及其他一些东西)的指针。所以在你的函数中你传递了一个指针(和其他一些东西)。然后你要附加指针。只是具体化并键入 switch 您的界面可能会很好。我假设你知道它可能是什么类型。在这种情况下,您必须按照以下方式进行操作:


package main


import (

    "fmt"

    "reflect"

)


type foo struct {

    fooval string

}


type bar struct {

    barval string

}


func main() {

    f1 := foo{"hi"}

    f2 := &foo{"hi"}

    b1 := bar{"bye"}

    b2 := &bar{"bye"}


    doSomething(f1)

    doSomething(f2)

    doSomething(b1)

    doSomething(b2)


}


func doSomething(i interface{}) {

    n := reflect.TypeOf(i)

    // get a new one

    newn := reflect.New(n).Interface()

    // find out what we got and handle each case

    switch t := newn.(type) {

    case **foo:

        *t = &foo{"hi!"}

        fmt.Printf("It was a **foo, here is the address %p and here is the value %v\n", *t, **t)

    case **bar:

        *t = &bar{"bye :("}

        fmt.Printf("It was a **bar, here is the address %p and here is the value %v\n", *t, **t)

    case *foo:

        t = &foo{"hey!"}

        fmt.Printf("It was a *foo, here is the address %p and here is the value %v\n", t, *t)

    case *bar:

        t = &bar{"ahh!"}

        fmt.Printf("It was a *bar, here is the address %p and here is the value %v\n", t, *t)

    default:

        panic("AHHHH")

    }

}

您也可以继续value = reflect.New(query.structType).Interface()在循环内部调用,每次都会为您提供新的接口。每次追加后重新分配值。上次通过循环会使一个额外的虽然..


查看完整回答
反对 回复 2021-11-22
  • 1 回答
  • 0 关注
  • 144 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信