除了当前元素之外,我如何遍历该切片并将其传递到某个位置?似乎正如我们在文档中看到的那样,追加()函数修改了底层的切片。但不管怎样,我还是不知道怎么达到这个目标。
func main() {
args := []string{ "2", "3", "8" }
for i, _ := range args {
fmt.Println(append(args[:i], args[i+1:]...)) // or pass to function
}
fmt.Println(args)
}结果:
[3 8]
[3 8]
[3 8]
[3 8 8] // it is args now我所期望的:
[3 8]
[2 8]
[2 3]我已经看过这个为什么append()要修改提供的片?(见示例)
但是,对我来说,切片的容量是什么,我不明白为什么我会超过它。
发布于 2016-03-10 16:04:21
表现是最重要的原因。创建一个新的切片并将所有元素复制到其中是很昂贵的,因此切片代码不会在没有充分理由的情况下进行复制。但是,如果您超过了该片的容量,则通过复制基础片,它会以适当的数量增长。这意味着从append返回的片可能不是您传入的同一片。
最好的使用方式是:
args = append(args, newarg)如果使用子片,容量将保持不变,但切片中的视图会发生变化。这意味着缺失的元素仍然存在,但超出了新切片的范围。
这解释了代码的奇怪输出。每次都要打印append的结果,但不存储结果,这意味着args与您打印的结果不一样。
初始的args切片是3个元素大。对于每个索引i --也就是说,对于0、1和2 --您需要一个子切片args[:i],并将数组args[i+1:]的其余部分的所有元素附加到它。这意味着:
i args[:i] args[i+1:]... Result args
0 {} {"3", "8"} {"3", "8"} {"3", "8", "8"}
1 {"3"} {"8"} {"3", "8"} {"3", "8", "8"}
2 {"3", "8"} {} {"3", "8"} {"3", "8", "8"}tl;博士,您应该始终保存append的结果,如果您想复制一个副本以便您可以更改它,那么自己制作一个副本。
发布于 2016-03-10 15:46:29
追加总是尝试修改基础数组。
让我们看一下循环的第一次执行。
append(args[:0], args[0+1:]...)这样做是将片{3,8}追加到片{},因为args:0给出了一个在数组开始时结束的空片。这就是为什么您的数组显示为3 8 8,因为3 8被附加到数组中。阅读有关此在维基上的更多信息。
可以使用make设置默认容量,即
args := make([]string, 0, CAPACITY)您还可以检查片的容量。
a := []int{1,2,3}
fmt.Println(cap(a))
>>> 3最后,如果您不想每次都像Elwinar的回答那样重新记录数组,我建议将两个片段a:i和ai+1:传递给函数。
发布于 2016-03-10 17:05:33
Go程序设计语言规范 附加和复制切片 内置函数在普通切片操作中附加和复制辅助功能。对于这两个函数,结果与参数引用的内存是否重叠无关。 变量函数附加零或多个S类型的值x到S,这必须是片类型,并返回结果片,也是S类型。值x传递给...T类型的参数,其中T是S的元素类型,相应的参数传递规则适用。作为特例,追加还接受可指定键入[]字节的第一个参数,第二个字符串类型的参数后面跟着.此表单附加字符串的字节。 附加(s S,x ...T) S // T是S的元素类型 如果s的容量不足以满足附加值,则追加一个新的、足够大的基础数组,该数组既适合现有的片元素,也适合附加的值。否则,追加重新使用基础数组。 s0 := []int{0,0} s1 := append(s0,2) //追加单个元素s1 == []int{0,0,2} s2 :=追加(s1,3,5,7) //附加多个元素s2 == []int{0,0,2,3,5,7} s3 :=附加(s2,s0.) //追加片s3 s0 []int{0,0,2,3,5,7,0,0} s4 :=追加(S33:6,s32:.) //追加重叠切片s4 == []int{3,5,7,2,3,5,7,0,0} var t[]接口{}t= append(t,42,3.1415,"foo") // t == []接口{42,3.1415,"foo"} var b[]b= append(b,//追加字符串内容b == []字节{‘b’,'a','r‘} 函数复制将片元素从源src复制到目标dst,并返回复制的元素数。这两个参数必须具有相同的元素类型T,并且必须分配给类型[]T的一个片段。复制的元素数是len(src)和len(dst)的最小值。作为特例,copy还接受一个指定为使用字符串类型的源参数键入[]字节的目标参数。此表单将字节从字符串复制到字节片中。 复制(dst,src []T) int复制(dst[]字节,src字符串) int 示例: var a= ...int{0,1,2,3,4,5,6,7} var s= make([]int,6) var b=make([]字节,5) n1 := copy(s,a0:) / n1 == 6,s == []int{0,1,2,3,4,5} n2 := copy(s,s2:) // n2 == 4,s == []int{2,3,4,5,4,4,5} n3 :=复制(b,"Hello,World!") // n3 == 5,b == []字节(“Hello”)
不要使用附件覆盖您的输入。为输出使用单独的变量(函数参数)。例如,
package main
import "fmt"
func main() {
args := []string{"2", "3", "8"}
fmt.Println(args)
funcArg := make([]string, len(args)-1)
for i := range args {
copy(funcArg, args[:i])
copy(funcArg[i:], args[i+1:])
fmt.Println(funcArg)
}
fmt.Println(args)
}输出:
[2 3 8]
[3 8]
[2 8]
[2 3]
[2 3 8]https://stackoverflow.com/questions/35920534
复制相似问题