仅从切片中获取初始化的内容
Get only the initialized content from a slice
我将未知数量的项目(大约 10.000)附加到切片中
le := 500
l := make([]string, le)
l = append(l, "a")
l = append(l, "b")
l = append(l, "c")
l = append(l, "d")
l = append(l, "...")
for i, v := range l{
fmt.Printf("i:%d-v:%s\n", i, v)
}
在此之后我的幻灯片包含
i:0-v:
...
i:500-v:a
i:501-v:b
i:502-v:c
i:503-v:d
i:504-v:e
我正在寻找一种方法来仅获取切片中存储的已初始化项目。
我想摆脱 i:0-v:
到 i:499-v:
我可以得到想要的结果重新切片l
,删除切片的第一个元素(第一个元素的数量取决于传递给[=17=的length
参数]方法)。
l = l[le:]
for j, k := range l{
fmt.Printf("i:%d-v:%s\n", j, k)
}
我的问题是:这是实现此目的的正确方法还是有更好的方法来删除在追加过程中添加的未初始化的项目?
为什么不做一个空切片,
// create a slice with len 0
l := []string{}
l = append(l, "a")
l = append(l, "b")
l = append(l, "c")
l = append(l, "d")
l = append(l, "...")
会给出一个输出,
i:0-v:a
i:1-v:b
i:2-v:c
i:3-v:d
i:4-v:...
您可以使用提供的 0 长度和容量创建切片,内置 make()
函数采用可选的第三个参数作为容量:
l := make([]string, 0, 1000) // Use a capacity that is enough for you
如果当前容量不足以执行追加,您可以通过这种方式追加元素,而 append()
不必重新分配(并隐式复制)内容。
另请注意,使用索引设置元素比追加更有效(通过使用 append()
您必须将返回的切片 header 分配回来,即使大多数时候它不会变化):
c, l := 0, make([]string, 1000) // Use a length that is enough for you
l[c], c = "a", c+1
l[c], c = "b", c+1
l[c], c = "c", c+1
l[c], c = "d", c+1
l[c], c = "e", c+1
// We're done: slice the slice:
l = l[:c]
for i, v := range l {
fmt.Printf("i:%d-v:%s\n", i, v)
}
输出(在 Go Playground 上尝试):
i:0-v:a
i:1-v:b
i:2-v:c
i:3-v:d
i:4-v:e
另请注意,在实践中,当您使用从某处接收到的值填充切片时,不需要手动计数器处理,循环会处理。例如:
c := 0
for ; c < 5; c++ {
l[c] = string('a' + c) // Acquire next element to store in the slice
}
// We're done: slice the slice:
l = l[:c]
在 Go Playground 上试试这个。
请注意,如果您创建的切片肯定不会很小,您只能使用它,否则 l[c]
会在 c
达到长度时给您带来运行时恐慌.
我将未知数量的项目(大约 10.000)附加到切片中
le := 500
l := make([]string, le)
l = append(l, "a")
l = append(l, "b")
l = append(l, "c")
l = append(l, "d")
l = append(l, "...")
for i, v := range l{
fmt.Printf("i:%d-v:%s\n", i, v)
}
在此之后我的幻灯片包含
i:0-v:
...
i:500-v:a
i:501-v:b
i:502-v:c
i:503-v:d
i:504-v:e
我正在寻找一种方法来仅获取切片中存储的已初始化项目。
我想摆脱 i:0-v:
到 i:499-v:
我可以得到想要的结果重新切片l
,删除切片的第一个元素(第一个元素的数量取决于传递给[=17=的length
参数]方法)。
l = l[le:]
for j, k := range l{
fmt.Printf("i:%d-v:%s\n", j, k)
}
我的问题是:这是实现此目的的正确方法还是有更好的方法来删除在追加过程中添加的未初始化的项目?
为什么不做一个空切片,
// create a slice with len 0
l := []string{}
l = append(l, "a")
l = append(l, "b")
l = append(l, "c")
l = append(l, "d")
l = append(l, "...")
会给出一个输出,
i:0-v:a
i:1-v:b
i:2-v:c
i:3-v:d
i:4-v:...
您可以使用提供的 0 长度和容量创建切片,内置 make()
函数采用可选的第三个参数作为容量:
l := make([]string, 0, 1000) // Use a capacity that is enough for you
如果当前容量不足以执行追加,您可以通过这种方式追加元素,而 append()
不必重新分配(并隐式复制)内容。
另请注意,使用索引设置元素比追加更有效(通过使用 append()
您必须将返回的切片 header 分配回来,即使大多数时候它不会变化):
c, l := 0, make([]string, 1000) // Use a length that is enough for you
l[c], c = "a", c+1
l[c], c = "b", c+1
l[c], c = "c", c+1
l[c], c = "d", c+1
l[c], c = "e", c+1
// We're done: slice the slice:
l = l[:c]
for i, v := range l {
fmt.Printf("i:%d-v:%s\n", i, v)
}
输出(在 Go Playground 上尝试):
i:0-v:a
i:1-v:b
i:2-v:c
i:3-v:d
i:4-v:e
另请注意,在实践中,当您使用从某处接收到的值填充切片时,不需要手动计数器处理,循环会处理。例如:
c := 0
for ; c < 5; c++ {
l[c] = string('a' + c) // Acquire next element to store in the slice
}
// We're done: slice the slice:
l = l[:c]
在 Go Playground 上试试这个。
请注意,如果您创建的切片肯定不会很小,您只能使用它,否则 l[c]
会在 c
达到长度时给您带来运行时恐慌.