英文:
Is Golang's ... syntax really just varargs?
问题
好的,以下是翻译的内容:
嗯,我有一个简单的例子,虽然可能看起来毫无意义,但这些例子与我的认知相去甚远。
有人可以告诉我发生了什么吗?
我使用...
语法将[]int
中的元素传递给参数args
,但当我改变形式参数args
时,[]int
的实际参数也被改变了。
我修改了args
的顺序,但[]int
的顺序也受到了影响:
package main
import (
"fmt"
)
func bubbleSort(args ...int) {
for i := 0; i < len(args); i++ {
for j := 0; j < len(args)-1; j++ {
if args[j] > args[j+1] {
args[j], args[j+1] = args[j+1], args[j]
}
}
}
}
func main() {
isle := []int{3, 6, 1, 2, 5}
bubbleSort(isle...)
fmt.Printf("%v\n", isle)
}
// [1 2 3 5 6]
如果我传入单个参数会怎样?显然[]int
不会受到args
的影响:
package main
import (
"fmt"
)
func bubbleSort(args ...int) {
for i := 0; i < len(args); i++ {
for j := 0; j < len(args)-1; j++ {
if args[j] > args[j+1] {
args[j], args[j+1] = args[j+1], args[j]
}
}
}
}
func main() {
isle := []int{3, 6, 1, 2, 5}
bubbleSort(isle[0], isle[1], isle[2], isle[3], isle[4])
fmt.Printf("%v\n", isle)
}
// [3 6 1 2 5]
英文:
Well, I have a simple example, although it may seem pointless, but these examples have deviated greatly from my cognition.
Can anyone tell me what happened.
I pass the elements in []int to the parameter args with the ... syntax, but when I change the formal parameter args, the []int actual parameter is changed.
I modified the ordering of args , but the ordering of []int is also affected:
package main
import (
"fmt"
)
func bubbleSort(args ...int) {
for i := 0; i < len(args); i++ {
for j := 0; j < len(args)-1; j++ {
if args[j] > args[j+1] {
args[j], args[j+1] = args[j+1], args[j]
}
}
}
}
func main() {
isle := []int{3, 6, 1, 2, 5}
bubbleSort(isle...)
fmt.Printf("%v\n", isle)
}
// [1 2 3 5 6]
What if I pass in a single parameter? Apparently []int is not affected by args:
package main
import (
"fmt"
)
func bubbleSort(args ...int) {
for i := 0; i < len(args); i++ {
for j := 0; j < len(args)-1; j++ {
if args[j] > args[j+1] {
args[j], args[j+1] = args[j+1], args[j]
}
}
}
}
func main() {
isle := []int{3, 6, 1, 2, 5}
bubbleSort(isle[0], isle[1], isle[2], isle[3], isle[4])
fmt.Printf("%v\n", isle)
}
// [3 6 1 2 5]
答案1
得分: 1
Golang不像Rust那样关注"变量安全性"。因此,你永远不应该认为传递给函数的切片不会被破坏。
如果你想使用可变参数函数但又要传递切片,请进行复制:
func myUnsafeFunc(args ...int) {
// 它会改变args
}
func wantToSaveSliceFunc() {
myLovingSlice := []int{1,2,3}
myUnsafeFunc(append([]int(nil), slice...)...)
}
https://freshman.tech/snippets/go/copy-slices/
如果你记住spread operator ...
只是一种语法糖,就不会感到困惑。
除非有充分的理由(例如在fmt.Printf(...)中),不要在自己的API中使用它,而是优先使用显式的x []type
表示法而不是x ...type
:
func myUnsafeFunc(args []int) {
// 它会改变args
}
func wantToSaveSliceFunc() {
myLovingSlice := []int{1,2,3}
myUnsafeFunc(append([]int(nil), slice...))
}
虽然仍然需要复制切片,但从语义上来说更清晰。
英文:
Golang is not about "variable safety" as Rust. So you shoud never think that slice sent to function will not be corrupted.
If you want to use variadic functions but send slices, copy it:
func myUnsafeFunc(args ...int) {
// it will change args
}
func wantToSaveSliceFunc() {
myLovingSlice := []int{1,2,3}
myUnsafeFunc(append([]int(nil), slice...)...)
}
https://freshman.tech/snippets/go/copy-slices/
It's not confusing if you remember that spread operator ...
is just a shugar .
Do not use it in your own API without serious reasone (as in fmt.Printf(...) for example) prefer use of explicit x []type
notation over x ...type
:
func myUnsafeFunc(args []int) {
// it will change args
}
func wantToSaveSliceFunc() {
myLovingSlice := []int{1,2,3}
myUnsafeFunc(append([]int(nil), slice...))
}
it still requires copying of slice, but it's much clear by semantics
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论