(我是Go的新手。)
我正在研究以下leetcode问题:https://leetcode.com/problems/pascals-triangle/
package main
import "fmt"
func main() {
arrRes := [][]int{}
gen(5, arrRes)
fmt.Println(arrRes)
}
func gen(numRows int, arrRes [][]int) {
build(numRows, 0, arrRes)
}
func build(n int, level int, arrRes [][]int) {
if(n == level) {
return
}
arr := []int{}
if level == 0 {
arr = append(arr, 1)
} else if level == 1 {
arr = append(arr, 1, 1)
} else {
// get it out
tmp := arrRes[level-1]
arr = comb(tmp)
}
arrRes = append(arrRes, arr)
build(n, level+1, arrRes)
}
func comb(arr []int) []int{
// arr type init
tmpArr := []int{1}
for i:=1; i<len(arr); i++ {
sum := arr[i-1] + arr[i]
tmpArr = append(tmpArr, sum)
}
// go use val, not ref
tmpArr = append(tmpArr, 1)
return tmpArr;
}
我想定义一个累积变量arrRes := [][]int{}
并继续传递到递归函数中。我认为Go是按值传递,而不是按引用传递。 有没有办法保持这种模式?
我有两种替代方法:
传递全局变量。
将2D数组传递到func
中,然后返回新的2D数组。
https://github.com/kenpeter/go_tri/blob/master/tri_global.go
答案 0 :(得分:3)
(基本上)切片是三件事:长度,容量和指向基础数组的指针。 Go中的所有内容都是按值传递的,因此,当您将切片传递给函数时,您正在传递其当前长度,当前容量和指针的内存地址。对函数内部长度和容量的更改将作为副本进行,不会影响在函数调用中作为参数传递的切片的长度和容量。
打印切片不会打印其基础数组,它会基于(1)指向指针的指针,打印在切片中可见的基础数组部分(如果len = 0则可能不包含任何部分)。基础数组中应该对切片可见的第一个元素;和(2)slice变量中的长度。
如果您要修改函数内部切片的长度或容量,并且希望这些更改在函数外部可见,则可以返回切片以更新函数外部的上下文,就像append一样:
numbers := append(numbers, 27)
或者您可以将指针传递给切片:
func ChangeNumbersLenOrCap(numbers *[]int) {
// make your changes, no return value required
}
对于您的程序,看来可以通过指向int slices切片的指针来逃脱:
var arrRes *[][]int
...因为您没有在另一个函数边界上修改int切片。有些程序需要一个指向切片的指针,该切片指向int切片:
var arrRes *[]*[]int
这里有一些简单的编辑可以帮助您入门:
arrRes := [][]int{}
gen(5, &arrRes)
fmt.Println(arrRes)
}
func gen(numRows int, arrRes *[][]int) {
// ...
func build(n int, level int, arrRes *[][]int) {
// ...
tmp := *arrRes[level-1]
// ...
*arrRes = append(*arrRes, arr)
build(n, level+1, arrRes)