Go 如果一个函数将一个切片的元素复制到一个变量,它是使用指向该元素的指针还是使用副本?

Go 如果一个函数将一个切片的元素复制到一个变量,它是使用指向该元素的指针还是使用副本?,go,Go,示例情况: 有一个全局结构包含一个结构片 type stctUser struct { user string privilege int created time.Time } type stctAllUsers struct { sync.RWMutex slcUsers []stctUser } var strctAllUsers stctAllUsers 有一个函数想要对用户进行操作,为了减少锁定全局结构的时间,我想要抓取一个用户并释放锁 va

示例情况:

有一个全局结构包含一个结构片

type stctUser struct {
    user string
    privilege int
    created time.Time
}

type stctAllUsers struct {
    sync.RWMutex
    slcUsers []stctUser
}
var strctAllUsers stctAllUsers
有一个函数想要对用户进行操作,为了减少锁定全局结构的时间,我想要抓取一个用户并释放锁

var strctUserTemp stctUser
strctAllUsers.RLock
for a := range strctAllUsers.slcUsers {
    if tmpName == strctAllUsers.slcUsers[a].user {
        strctUserTemp = strctAllUsers.slcUsers[a]
        break
    }
}
strctAllUsers.RUnlock
strctUserTemp是使用slcUsers[a]的单独副本,还是指向该切片元素的指针?例如,strctAllUsers.slcUsers[a]是“Tom”,如果更改strctUserTemp.user=“Bob”,strctAllUsers.slcUsers[a]仍然是Tom吗

(以前,似乎将一个切片复制到一个新变量意味着对该新变量切片的更改可能会更改原始切片…因此它分配了一个指针,而不是创建一个副本。还是我记错了?)

更新:鉴于我太蠢了,没法花五分钟来测试这一点……这里有一个链接,指向一开始让我质疑这一点的行为,我想在假设我了解发生了什么并在实际工作中产生了一个bug之前澄清实现

最重要的是:作业总是复制的。但是,它可能是指针的副本

有三种基本情况:

  • 您有一部分值。将切片中的元素指定给局部变量,从而创建值的副本。局部变量和slice元素之间没有连接
  • 你有一片指针。将切片中的元素指定给局部变量,从而创建指针的副本。对指向值的更改将反映在slice元素的任何其他使用中,因为本地指针和slice中的指针指向相同的内存
  • 您有一部分值。将对切片中元素的引用分配给局部变量(例如,
    myVar:=&mySlice[0]
    )。局部变量包含由寻址表达式创建的引用的副本。对局部变量值的更改会通过slice元素的任何其他使用反映出来,因为局部指针直接指向保存该slice元素的内存

  • 请注意,最后一个选项意味着您将有一个脆弱的指针-如果您附加到切片,并且底层数组在内存中移动,您将得到一些令人困惑的行为。

    测试用户名更改有多困难?一分钟?但要回答你的问题:所有作业都要复印一份。如果指定结构值,将复制结构值(逐字段)。必须小心,就像一个字段是一个指针一样。例如,副本和原件将持有相同的指针,指向同一个对象。就像你说的一样,这是一个副本-你必须明确地把它作为一个指针,让它成为我刚才问的那样,因为我看到了我认为是矛盾的行为,我想确保我没有因为不了解它是如何实现的而遇到错误…但刺耳的回答仍然是回答,我想是吧。这就是我最初问这个问题的原因。添加了问题中的更新链接感谢您提供的信息;你能详细说明一下我添加到问题中的游乐场链接中发生了什么吗?它几乎有一百行,你能澄清你在问的是哪一部分吗?第55-64行,将切片复制到输出中的变量so#3中?你正在复制一份切片。这两个副本都指向同一个底层数组,因此对其中一个元素的更改会反映在另一个数组中。好的,那么到切片的=实际上是一组指针,但到元素的=会复制所指向的内容。