猿问

分配的指针字段变为 <nil>

我有一个结构:


type user struct {

Id string

..

data_ptr *userData

}

我将用户切片存储在全局范围内:


type Hall struct {

    users []user

}


var hall = Hall{}    //global

最后,http 处理程序:


func dataHandler(response http.ResponseWriter, request *http.Request) {

    userExist, user_ptr := hall.haveUserId()    //works fine

    switch requestType {

    case "load":    

        user_ptr.loadData()   //data loaded and user_ptr.data_ptr is set

    case "newData":

        user_ptr.data_ptr = newData  // <-- this is it, now previously set data_ptr == nil

那么,到底为什么,我的意思是我发送“加载”请求,它加载数据,设置data_ptr为user_ptr. 但是在下一次调用“newData”请求时,user_ptr.data_ptr是nil?


以防万一,这里是loadData():


func (p *user) loadData(userId) {

    ..

    data := userData {}

    p.data_ptr = &data

}

编辑:其中user_ptr来自:


func (h *Hall) haveUserId(id string) (bool, *user) {

    for _, u := range h.users {

        if u.Id == id {

            fmt.Println("UID found")

            return true, &u

        }

    }

    return false, nil

}


长风秋雁
浏览 133回答 1
1回答

慕容3067478

这是因为您操作的是副本而不是切片元素本身。在您的haveUserId()函数中,它for ... range会复制它循环的元素,然后返回该副本的地址。稍后您将修改此副本,该副本与切片中的值无关。因此,如果稍后您检查切片元素中的地址,它仍然会保持不变(nil)。可能的解决方法:返回切片元素的地址: &h.users[i]func (h *Hall) haveUserId(id string) (bool, *user) {&nbsp; &nbsp; for i := range h.users {&nbsp; &nbsp; &nbsp; &nbsp; if h.users[i].Id == id {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("UID found")&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return true, &h.users[i]&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; return false, nil}为了证明这一点,请参见以下示例:type Point struct{ x, y int }ps := []Point{{1, 2}, {3, 4}}fmt.Println(ps) // Output: [{1 2} {3 4}]for _, v := range ps {&nbsp; &nbsp; v.x += 10 // Modifies just the copy}fmt.Println(ps) // Output (unchanged): [{1 2} {3 4}]for i := range ps {&nbsp; &nbsp; ps[i].x += 10 // Modifies value in slice}fmt.Println(ps) // Output (changed): [{11 2} {13 4}]
随时随地看视频慕课网APP

相关分类

Go
我要回答