从切片中获取仅已初始化的内容。

huangapple go评论76阅读模式
英文:

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, "...")

然后,我的切片包含以下内容:

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来获得所需的结果,以删除切片的前几个元素(前几个元素的数量取决于传递给make方法的length参数)。

l = l[le:]
for j, k := range l{
    fmt.Printf("i:%d-v:%s\n", j, k)
}

我的问题是:这是实现这一目标的正确方法吗?还是有更好的方法来去除在添加过程中未初始化的项目?

英文:

I append an unknown number of items (arround 10.000) into a slice

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)
}

After this my slide contains

i:0-v:
...
i:500-v:a
i:501-v:b
i:502-v:c
i:503-v:d
i:504-v:e

I'm looking for a way to get only the initialized items stored in the slice.
I want to be rid of i:0-v: to i:499-v:

I can get the desired result re-slicing l, to remove the first elements of the slice (the number of first elements dépends on the length parameter passed to the make method).

l = l[le:]
for j, k := range l{
    fmt.Printf("i:%d-v:%s\n", j, k)
}

My question is: Is it the right way to achieve this or is there a nicer way to get rid of the items not initialized, added during the append?

答案1

得分: 3

为什么不创建一个空的切片,

// 创建一个长度为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:...

示例

英文:

Why not make an empty slice,

// 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, "...")

will give an output,

i:0-v:a
i:1-v:b
i:2-v:c
i:3-v:d
i:4-v:...

Example

答案2

得分: 3

你可以使用提供的长度和容量创建一个切片,内置的make()函数接受一个可选的第三个参数作为容量:

l := make([]string, 0, 1000) // 使用足够的容量

这样你可以在不需要`append()`重新分配并隐式复制内容的情况下追加元素如果当前容量不足以执行追加操作

还要注意使用索引设置元素比追加更高效使用`append()`即使大多数情况下返回的切片头部不变你仍然需要将其赋值回去):

```go
c, l := 0, make([]string, 1000) // 使用足够的长度

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

// 完成后,对切片进行切片操作:
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) // 获取下一个要存储在切片中的元素
}

// 完成后,对切片进行切片操作:
l = l[:c]

Go Playground上尝试这个例子。

请注意,只有在你创建的切片足够大的情况下才能使用这种方法,否则当c达到长度时,l[c]会导致运行时恐慌。

英文:

You may create a slice using 0 length and capacity provided, the builtin make() function takes an optional 3rd parameter being the capacity:

l := make([]string, 0, 1000) // Use a capacity that is enough for you

This way you can append elements without append() having to reallocate (and implicitly copy) the contents if the current capacity is not enough to perform the append.

Also note that it is more efficient to set elements using indexing than appending (by using append() you have to assign the returned slice header back even though most of the time it doesn't change):

c, l := 0, make([]string, 1000) // Use a length that is enough for you

l[c], c = &quot;a&quot;, c+1
l[c], c = &quot;b&quot;, c+1
l[c], c = &quot;c&quot;, c+1
l[c], c = &quot;d&quot;, c+1
l[c], c = &quot;e&quot;, c+1

// We&#39;re done: slice the slice:
l = l[:c]

for i, v := range l {
	fmt.Printf(&quot;i:%d-v:%s\n&quot;, i, v)
}

Output (try it on the Go Playground):

i:0-v:a
i:1-v:b
i:2-v:c
i:3-v:d
i:4-v:e

Also note that in practice when you fill your slice with values you receive from somewhere, the manual counter handling is not needed, a loop takes care of that. For example:

c := 0
for ; c &lt; 5; c++ {
	l[c] = string(&#39;a&#39; + c) // Acquire next element to store in the slice
}

// We&#39;re done: slice the slice:
l = l[:c]

Try this one on the Go Playground.

Note that you can only use this though if you create a slice that you're sure won't be small, else l[c] would give you a runtime panic when c reaches the length.

huangapple
  • 本文由 发表于 2017年2月24日 23:20:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/42442207.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定