在Go语言中进行切片操作

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

Slice juggling in golang

问题

简而言之,这是一个交易:<br>
http://play.golang.org/p/ePiZcFfPZP

<hr>
如果我使用注释掉的行,一切都正常,但是没有<br>
对分配大小(cap)进行任何控制,所以切片,<br>
如果我理解正确的话,每次超过限制时都会重新分配<br>
而且它们的初始容量为零。

setSlice()中传递newSlice的引用也不起作用。

所以,我需要一种符合Go语言习惯、优雅的方法来完成这个任务。
<hr>
提前感谢,至少感谢你的关注和时间。
<br><br>
<s>更新:
解决方法是将SLICESTASH的类型设置为*[]byte<br>
并进行如下赋值:

  1. var slicePtr *[]byte
  2. tmp := make([]byte, 256)
  3. slicePtr = &amp;tmp // Tmp is needed because we can&#39;t take adress of make() rval.

</s>

英文:

To be short, here is a deal: <br>
http://play.golang.org/p/ePiZcFfPZP

<hr>
If I use commented lines, everything works, but there is no<br>
any control on allocation sizes (cap), so the slices,<br>
if I got it correct, realloc every time they exceed their limit<br>
and moreover, they start with zero capacity.

Passing a reference of newSlice in setSlice() don't work too.

So, I need ideomatic, elegant, go-ish method to do the job.
<hr>
Thanks in advance, at least for attention and your time.
<br><br>
<s>UPD:
solution was to make SLICE and STASH *[]byte typed<br>
and make assigns to them like:

  1. var slicePtr *[]byte
  2. tmp := make([]byte, 256)
  3. slicePtr = &amp;tmp // Tmp is needed because we can&#39;t take adress of make() rval.

</s>

答案1

得分: 0

例如,

  1. package main
  2. import "fmt"
  3. var SLICE, STASH []byte
  4. func init() {
  5. SLICE = make([]byte, 0, 5)
  6. }
  7. func setSlice(slice []byte) {
  8. STASH = SLICE
  9. SLICE = slice
  10. }
  11. func restoreSlice() {
  12. SLICE = STASH
  13. }
  14. func appendToSlice(parts ...byte) []byte {
  15. SLICE = append(SLICE, parts...)
  16. return SLICE
  17. }
  18. func main() {
  19. appendToSlice('f', 'o', 'o')
  20. fmt.Printf("一切正常: {'%s'}\n", SLICE)
  21. newSlice := make([]byte, 0, 5)
  22. setSlice(newSlice)
  23. newSlice = appendToSlice('b', 'a', 'r')
  24. fmt.Printf("Bar? 不! {'%s'}\n", newSlice) // <- 我需要 "bar" 出现在 newSlice 中。
  25. fmt.Printf("Bar 在这里: {'%s'}\n", SLICE)
  26. restoreSlice()
  27. fmt.Printf("回到原点. {'%s'}\n", SLICE)
  28. }

输出:

  1. 一切正常: {'foo'}
  2. Bar? 不! {'bar'}
  3. Bar 在这里: {'bar'}
  4. 回到原点. {'foo'}

与 Go 的 append 内置函数一样,你的 appendToSlice 函数需要返回追加的结果。

  1. func appendToSlice(parts ...byte) []byte {
  2. SLICE = append(SLICE, parts...)
  3. return SLICE
  4. }

  1. newSlice = appendToSlice('b', 'a', 'r')

Go 编程语言规范

追加和复制切片

内置函数 append 和 copy 用于常见的切片操作。对于这两个函数,结果与参数引用的内存是否重叠无关。

可变参数函数 append 将零个或多个值 x 追加到类型为 S 的切片 s 中,并返回结果切片,类型也为 S。

如果 s 的容量不足以容纳额外的值,则 append 分配一个新的足够大的底层数组,该数组同时适应现有的切片元素和额外的值。否则,append 会重用底层数组。

示例:

  1. var b []byte
  2. b = append(b, "bar"...) // 追加字符串内容;b == []byte{'b', 'a', 'r'}
英文:

For example,

  1. package main
  2. import &quot;fmt&quot;
  3. var SLICE, STASH []byte
  4. func init() {
  5. SLICE = make([]byte, 0, 5)
  6. }
  7. func setSlice(slice []byte) {
  8. STASH = SLICE
  9. SLICE = slice
  10. }
  11. func restoreSlice() {
  12. SLICE = STASH
  13. }
  14. func appendToSlice(parts ...byte) []byte {
  15. SLICE = append(SLICE, parts...)
  16. return SLICE
  17. }
  18. func main() {
  19. appendToSlice(&#39;f&#39;, &#39;o&#39;, &#39;o&#39;)
  20. fmt.Printf(&quot;Everything is fine: {&#39;%s&#39;}\n&quot;, SLICE)
  21. newSlice := make([]byte, 0, 5)
  22. setSlice(newSlice)
  23. newSlice = appendToSlice(&#39;b&#39;, &#39;a&#39;, &#39;r&#39;)
  24. fmt.Printf(&quot;Bar? No! {&#39;%s&#39;}\n&quot;, newSlice) // &lt;- I need &quot;bar&quot; appear in newSlice.
  25. fmt.Printf(&quot;Bar is here: {&#39;%s&#39;}\n&quot;, SLICE)
  26. restoreSlice()
  27. fmt.Printf(&quot;Back to origin. {&#39;%s&#39;}\n&quot;, SLICE)
  28. }

Output:

  1. Everything is fine: {&#39;foo&#39;}
  2. Bar? No! {&#39;bar&#39;}
  3. Bar is here: {&#39;bar&#39;}
  4. Back to origin. {&#39;foo&#39;}

Like the Go append built-in function, your appendToSlice function needs to return the result of the append.

  1. func appendToSlice(parts ...byte) []byte {
  2. SLICE = append(SLICE, parts...)
  3. return SLICE
  4. }

and

  1. newSlice = appendToSlice(&#39;b&#39;, &#39;a&#39;, &#39;r&#39;)

> The Go Programming Language Specification
>
> Appending to and copying slices
>
> The built-in functions append and copy assist in common slice
> operations. For both functions, the result is independent of whether
> the memory referenced by the arguments overlaps.
>
> The variadic function append appends zero or more values x to s of
> type S, which must be a slice type, and returns the resulting slice,
> also of type S.
>
> If the capacity of s is not large enough to fit the additional values,
> append allocates a new, sufficiently large underlying array that fits
> both the existing slice elements and the additional values. Otherwise,
> append re-uses the underlying array.
>
> Example:
>
> var b []byte
> b = append(b, "bar"...) // append string contents; b == []byte{'b', 'a', 'r' }

huangapple
  • 本文由 发表于 2014年9月8日 06:04:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/25715193.html
匿名

发表评论

匿名网友

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

确定