为啥 golang 切片赋值默认是地址呀

2018-08-17 14:41:09 +08:00
 zarte

代码是这样的 ,要实现建立一个新的二维数组
变得要多写一行

  var newserverlist  [][]string  
	for _, addr := range serverlist {  
      tmpaddr=addr 这样 newserverlist 会是一个值一样的数组
		for i:=0;i<len(filearr);i++{    
          
          
			//tmpaddr := make([]string,len(addr))  
			//copy(tmpaddr,addr)  
              
			tmpaddr[1] = filearr[i][0]  
			tmpaddr[3] = filearr[i][1]  
			newserverlist = append(newserverlist,tmpaddr)  
			fmt.Println(newserverlist)  
            }  
          }  
1860 次点击
所在节点    Go 编程语言
1 条回复
Lpl
2018-08-17 16:22:43 +08:00
slice 里边存了三个值:底层数组指针、长度、容量。
如果直接:tmpaddr = addr,那么你只是把切片复制了一份,其中:底层数组指针、长度、容量,都没有变化。

你的目的应该是把 serverList 这个切片复制出来一个新切片,那么这种方式是可行的:
tmpaddr := make([]string,len(addr))
copy(tmpaddr,addr)

例子:
func main() {
serverList := [][]string {
{"a", "b", "c"},
{"aa", "bb", "cc"},
}
fmt.Println(serverList[0]) // => [a b c]
changeSlice(serverList[0])
fmt.Println(serverList[0]) // => [changed b c]
}

func changeSlice(slice []string) {
slice[0] = "changed"
}

函数 changeSlice 接受了一个 slice 的复制体做实参,此复制体与原 slice 存储了相同的指向原始数组的指针,在函数 changeSlice 中修改 slice 指向数组的值,对于原 slice 也是可见的

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/480725

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX