H5W3
当前位置:H5W3 > go > 正文

【go】golang string slice作为函数参数传递的问题

package main
func Sample(args []string) {
args = append(args, "D", "E")
}
func main() {
args := []string{}
args = append(args, "A","B","C")
Sample(args)
for _, arg := range args {
println(arg)
}
}

比如在上面这个程序(https://play.golang.org/p/0Ch…)里,我希望Sample函数执行完成之后,args里面的结果是ABCDE,但是真实的结果是ABC。

这跟我对slice的理解不一样啊。

我试了一下,在Sample函数里是可以对里面的string做修改的,

package main
func Sample(args []string) {
args[2] = "F"
}
func main() {
args := []string{}
args = append(args, "A","B","C")
Sample(args)
for _, arg := range args {
println(arg)
}
}

上面这个程序(https://play.golang.org/p/Y81…)就把args的最后一个元素改成F了。

还是说因为string也是变长的结构,所以函数在传參的时候就把args的长度固定住了。这是什么原理啊。

func Sample(args []string) {
println(len(args))
println(cap(args))
println(args)
args = append(args, "D", "E")
println(len(args))
println(cap(args))
println(args)
}

会发生扩容,args的地址已经改了,内部的数组也已经变了。
但是go中只有值传递,所以外面的args还是引用前面的数组。
可以将args返回解决。

package main
func Sample(args *[]string) {
*args = append(*args, "D", "E")
}
func main() {
args := []string{}
args = append(args, "A", "B", "C")
Sample(&args)
for _, arg := range args {
println(arg)
}
}

最简单的办法就是这样了
另一种方式,就是在Sample方法中,返回数组
其实就是值传递和指针传递的问题,你可以去搜一些相关资料,看一下就明白了

首先golang只有值传递, slice传递的是reflect.SliceHeader的copy, 其中的Data字段指向底层数组, append扩容导致底层数组重新分配,即Data的指向发生了变化.args[2] = "F"仅修改了底层数组的值,Data的指向不变.

你可看看golang官方的slice介绍Go Slices: usage and internals.

回答

本文地址:H5W3 » 【go】golang string slice作为函数参数传递的问题

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址