关于golang的append函数的踩坑

从LeetCode第26题产生的疑问

这篇文章里面提到了关于在函数内部修改数据的情况。但是LeetCode22题中发现append无法在传送变量中进行append。

测试代码

输出结果
[123 456 7] //使用test函数append数字8,但是并没有修改原数据的值
[1 2 3] //同理,只可以在main函数append成功
[1 2 4] //但是可以修改数据的值,append失效的原因待查

package main

import "fmt"

func main() {
	nums := []string{}
	nums = append(nums, "123")
	nums = append(nums, "456")
	nums = append(nums, "7")

	test(nums)
	fmt.Println(nums)

	num := []int{}
	num = append(num, 1)
	num = append(num, 2)
	num = append(num, 3)

	fmt.Println(num)
	test1(num)
	fmt.Println(num)
}


func test1(num []int) {
	// append无法更改值。
	num = append(num, 4)
	num[2] = 4
}


func test(nums []string) {
	nums = append(nums, "8")
}

LeetCode22

在做这个题其中nums = append(nums, s),将所有符合条件的结果存储在nums中,但是return之后nums为空,发现nums无法修改数据的值

package main

import "fmt"

func generateParenthesis(n int) []string {
	nums := make([]string, 0)
	generate("",nums, n, n)
	return nums
}

func generate(s string, nums []string, left int,right int ) {
	if left == 0 && right == 0 {
		nums = append(nums, s)
		return
	}

	if left > 0 {
		generate(s + "(", nums, left - 1, right)
	}
	if right > left {
		generate(s + ")", nums, left, right - 1)
	}
}

func main(){
	x := generateParenthesis(2)
	fmt.Println(x)
}

解决方式

func main() {
	nums := []string{}
	nums = append(nums, "123")
	nums = append(nums, "456")
	nums = append(nums, "7")
	test(&nums)
	fmt.Println(nums)
}

func test(nums *[]string) {
	*nums = append(*nums, "8")
}

原题

https://blog.csdn.net/csdn_kou/article/details/104307631
为什么返回数值是整数,但输出的答案是数组呢?

请注意,输入数组是以“引用”方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。

你可以想象内部操作如下:

// nums 是以“引用”方式传递的。也就是说,不对实参做任何拷贝
int len = removeDuplicates(nums);

// 在函数里修改输入数组对于调用者是可见的。
// 根据你的函数返回的长度, 它会打印出数组中该长度范围内的所有元素。

例2 LeetCode189

https://leetcode-cn.com/problems/rotate-array
append 拼接过程中重新创建了底层数组,导致函数中的 nums 不再是函数外的 nums,引用失效。
其实也证明go中没有引用类型,因为go不存在引用赋值
测试代码

package main

import "fmt"

func rotate(nums []int, k int)  {
	tx := &nums
	te := reverse(&nums,k)
	*tx = te
	fmt.Println("2", nums)
}

func reverse(nums *[]int, k int) []int{
	*nums = append(*nums, 8)
	return *nums
}

func main(){
	nums := []int{1,2,3,4,5,6,7}
	rotate(nums, 3)
	fmt.Println("1", nums)
}

189题使用这样的方式改变了数组的值

func rotate(nums []int, k int)  {
    k %= len(nums)
    ans := append(nums[len(nums)-k:], nums[:len(nums)-k]...)
    nums = append(nums[:0], ans...)
}

测试是否可以改变原数组。这个小细节可以记一下

package main

import "fmt"

func t(nums []int) {
	// 1 Right
	//ans := append(nums[:2], nums[1])
	//nums = append(nums[:0], ans...)
	// 2 Right
	//ans := append(nums[:2], 1)
	//nums = append(nums[:0], ans...)
	// 3 False
	//ans := append(nums, 1)
	//nums = append(nums[:0], ans...)
	// 4 Right
	//ans := append(nums[:len(nums)-1], 1)
	//nums = append(nums[:0], ans...)
	// 5 Right
	//ans := append(nums[:1], 1)
	//nums = append(nums[:0], ans...)
	// 6 False
	ans := append(nums[:0], 1)
	nums = append(nums[:0], ans...)
}


func main() {
	nums := []int {1,2,3}
	t(nums)
	fmt.Println(nums)
}

发布了356 篇原创文章 · 获赞 247 · 访问量 36万+

猜你喜欢

转载自blog.csdn.net/csdn_kou/article/details/104653189
今日推荐