英文:
Go recursion for struct fields - function vs. pointer method
问题
给定一个示例代码:
type container struct {
arr []int
}
我想要递归地操作它的arr
数组字段值。
我有两个选项,从功能上来说:
- 在
container
上使用(指针接收者) 方法,直接访问它的arr
数组 - 使用一个函数,接收
arr
切片作为参数
无论哪种情况,每个递归调用都必须传递交替的起始和结束索引作为参数。
问题:
使用其中一种实现方式是否会有已知的理论上的好处或不利影响,主要考虑性能和内存占用,假设arr
将包含10^6
到10^9
个元素之间的数量?
注:通过运行(非专业的基准测试)的实现,性能似乎没有显著差异。
英文:
Given an exemplary
type container struct {
arr int[]
}
I want to recursively manipulate its arr
array field values.
I have two options, functionally:
- a (pointer receiver) method on
container
, directly accessing itsarr
array - a function, receiving the
arr
slice as parameter
In any case, alternating start and end indices have to be passed as parameters to each recursive call.
Question:<br>
Are there any known, theoretically beneficial or detrimental impacts, mainly with regards to performance¹ and memory footprint, by using one implementation over the other and considering that arr
will hold between 10^6
and 10^9
elements?
¹ running (unprofessionally bench-marked) test implementations, performance does not seem to be significantly different
答案1
得分: 2
我认为你可以使用两种选项,但我建议使用指向数组的指针,因为它可以防止意外追加切片,从而导致整个切片内存的复制。
另外请注意,你不能以这种方式使用数组:
func foo(sl []int) {
sl[1] = 15
}
func main() {
arr := [5]int{1, 2, 3, 4, 5}
foo(arr)
}
输出:
cannot use arr (variable of type [5]int) as []int value in argument to foo
但你可以将数组转换为切片而不进行复制:
package main
import (
"fmt"
)
func foo(sl []int) {
sl[1] = 55
}
func main() {
arr := [5]int{1, 2, 3, 4, 5}
sl := arr[:]
fmt.Printf("arr=%v, sl=%v\n", arr, sl)
arr[1] = 5
fmt.Printf("arr=%v, sl=%v\n", arr, sl)
sl[1] = 15
fmt.Printf("arr=%v, sl=%v\n", arr, sl)
foo(sl)
fmt.Printf("arr=%v, sl=%v\n", arr, sl)
}
输出:
arr=[1 2 3 4 5], sl=[1 2 3 4 5]
arr=[1 5 3 4 5], sl=[1 5 3 4 5]
arr=[1 15 3 4 5], sl=[1 15 3 4 5]
arr=[1 55 3 4 5], sl=[1 55 3 4 5]
英文:
I think that you can use both options, but I recommend to use pointer to array because it will protect you from accidental append to the slice which can lead to copying of the entire slice memory.
Also keep in mind that you cannot use array in such way:
func foo(sl []int) {
sl[1] = 15
}
func main() {
arr := [5]int{1, 2, 3, 4, 5}
foo(arr)
}
Output:
cannot use arr (variable of type [5]int) as []int value in argument to foo
But you can convert array into slice without copying it:
package main
import (
"fmt"
)
func foo(sl []int) {
sl[1] = 55
}
func main() {
arr := [5]int{1, 2, 3, 4, 5}
sl := arr[:]
fmt.Printf("arr=%v, sl=%v\n", arr, sl)
arr[1] = 5
fmt.Printf("arr=%v, sl=%v\n", arr, sl)
sl[1] = 15
fmt.Printf("arr=%v, sl=%v\n", arr, sl)
foo(sl)
fmt.Printf("arr=%v, sl=%v\n", arr, sl)
}
Output:
arr=[1 2 3 4 5], sl=[1 2 3 4 5]
arr=[1 5 3 4 5], sl=[1 5 3 4 5]
arr=[1 15 3 4 5], sl=[1 15 3 4 5]
arr=[1 55 3 4 5], sl=[1 55 3 4 5]
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论