楼主只是简单想测试一下切片的删除头和删除中间的部分,所以写了一个小demo测试一下,但是运行结果却很让我出乎意料
先贴上代码:
package main
import "fmt"
func main() {
fmt.Println("测试:")
var st []int
for i:=0;i<12;i++{
st=append(st,i)
}
fmt.Println("原切片:")
fmt.Println(st)
fmt.Println("删除切片指定头:")
test1(st,2)
fmt.Println(st)
fmt.Println("删除切片指定位置:")
test2(st,5)
fmt.Println(st)
}
// 去除切片头,测试切片是否为引用传递?
func test1(s []int,i int){
s = s[i:]
}
//去除中间
func test2(s []int,i int) {
// 和js6类似s[]...表示将数组转化为一列参数输入
s = append(s[:i],s[i+2:]...)
}
以下是运行结果
测试:
原切片:
[0 1 2 3 4 5 6 7 8 9 10 11]
删除切片指定头:
[0 1 2 3 4 5 6 7 8 9 10 11]
删除切片指定位置:
[0 1 2 3 4 7 8 9 10 11 10 11]
Process finished with exit code 0
可以看到删除头的操作并没有成功
楼主一开始的理解是,go语言所有参数传递默认是值传递,所以传递过去的切片只是一个副本,在函数内部改变切片值是不起作用的
但是下面这个函数的运行s = append(s[:i],s[i+2:]...)
就诡异了
原数组[0 1 2 3 4 5 6 7 8 9 10 11],输入值为2,运行结果是下面这个:
[0 1 2 3 4 7 8 9 10 11 10 11]
切片中间的5,6的确是删除了,可以看到切片的确是以引用的形式传到了函数内部,但后面的两位出现了重复,这是什么鬼?
百般思索下,觉得是在函数里不能对原切片的cap和len进行修改,只能作值的修改?切片映射的原数组会自动填补上缺失的部分?但是第一个函数也删去了切片的头值,但切片根本就没变啊?
求大佬们解决一下萌新的疑惑QAQ
有疑问加站长微信联系(非本文作者)

你打印的还是st,并不是操作后的切片,你应该用指针或者函数定义时返回结果切片
默默问一句,如果我不想写返回值的话,能否在test函数内部直接操作main里切片st,并反映到main?如果可以的话怎么实现呢?
golang里没有删除这个操作。
append到底是做什么的你也需要了解一下。
函数直接用切片参数不行,你要想达到效果,参数要是a *[]int才行 package main
import "fmt"
func test(s []int) { s = (*s)[1:] }
func main() { s := []int{1,2,3,4,5} fmt.Println(s) test(&s) fmt.Println(s) }
谢谢,果然用指针就能成功
append我看官方注释是给切片追加数的功能:
The append built-in function appends elements to the end of a slice
函数里用指针确实我的功能就能跑通了,感觉go不能老用面向对象的思想,以后还是写成返回值的形式吧
只是有点好奇为啥不用指针的时候,在函数里append切片,main里面的原来切片会受到影响,估计是append函数的问题
可惜看不到append函数的实现方式
append的名字起得是个坑。
其实是这样的,组合两个数组。
如果第一个数组空间够,返回第一个数组。 如果第一个数组空间不够,返回一个新的足够大的数组……
原来如此,感情是test函数里切片覆盖了原数组的一部分,这样就解释的通了,的确是挺坑的
感谢大佬
append只对切片有效,你可以试试s[:i]=append(s[i+2:]) return s[:I]
append只对切片有效,你可以试试s[:i]=append(s[:I],s[i+2:]) return s[:I]