在Golang,我正在尝试为我的旅行推销员问题制作一个争夺切片功能.虽然这样做我注意到当我开始编辑切片时,我给每个传递它时的加扰功能是不同的.
经过一些调试后我发现它是由于我编辑了函数内部的切片.但由于Golang应该是一种"通过价值传递"的语言,这怎么可能呢?
https://play.golang.org/p/mMivoH0TuV
我提供了一个游乐场链接来展示我的意思.通过删除第27行,您获得的输出与输入不同,这应该没有区别,因为该函数在作为参数传入时应该创建自己的切片副本.
有人可以解释这种现象吗?
我有以下功能:
func checkFiles(path string, excludedPatterns []string) {
// ...
}
Run Code Online (Sandbox Code Playgroud)
我想知道,因为excludedPatterns永远不会改变,我应该通过使var全局(而不是每次都将它传递给函数)来优化它,或者Golang是否已经通过将它们作为copy-on-write传递来处理它?
编辑:我想我可以将切片作为指针传递,但我仍然想知道写时复制行为(如果它存在)以及一般来说我是否应该担心通过值或指针传递.
我有以下代码:
func main() {
var buf []byte{1, 2, 3, 4, 5}
buf = buf[2:]
fmt.Println(buf)
panic(1)
}
Run Code Online (Sandbox Code Playgroud)
但是我想将指向buf字节切片的指针传递给另一个函数,并将其切片到那里,所以类似于:
func main() {
var buf []byte{1, 2, 3, 4, 5}
sliceArr(&buf, 2)
fmt.Println(buf)
panic(1)
}
func sliceArr(buf *[]byte, i int) {
*buf = *buf[i:]
}
Run Code Online (Sandbox Code Playgroud)
它给了我一个错误,我不能在函数的参数中使用type []byte作为类型,并且我不能切片类型.怎么了?默认情况下,切片是否通过引用传递?我尝试在没有指针的情况下执行此操作,但它不起作用 - 正在复制数组.我怎样才能做到这一点?*[]bytesliceArr()*[]byte
为什么在编辑切片内部函数不适用长度更新?
快速响应:因为切片只是对原始数组的引用
正如您在下面的示例中所看到的,我有一个切片,将通过外部函数在值中修改,但是在您从函数返回值并将其重新分配给原始切片之前,将完全忽略追加操作.
为了改进示例,我添加了通过引用传递的函数并进行修改操作以提高解决方案的舒适度
package main
import (
"fmt"
)
var sli = make([]int,8)
func main() {
fmt.Println("START STATUS_____")
fmt.Println("slice",sli)
fmt.Println(" cap:", cap(sli))
fmt.Println(" len:", len(sli))
editSli(sli)
fmt.Println("EDIT RESULT STATUS_____")
fmt.Println("slice",sli)
fmt.Println(" cap:", cap(sli))
fmt.Println(" len:", len(sli))
sli = updateSli(sli)
fmt.Println("UPDATE RESULT STATUS_____")
fmt.Println("slice",sli)
fmt.Println(" cap:", cap(sli))
fmt.Println(" len:", len(sli))
sli = append(sli, 15, 16, 17)
fmt.Println("DIRECT APPEND RESULT STATUS_____")
fmt.Println("slice",sli)
fmt.Println(" cap:", cap(sli))
fmt.Println(" len:", len(sli))
sli[13] = 99
fmt.Println("DIRECT ASSIGNMENT OF LAST ELEMENT (13°) STATUS_____")
fmt.Println("slice",sli)
fmt.Println(" cap:", …Run Code Online (Sandbox Code Playgroud)