在Go语言中进行切片操作

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

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>
并进行如下赋值:

var slicePtr *[]byte
tmp := make([]byte, 256)
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:

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

</s>

答案1

得分: 0

例如,

package main

import "fmt"

var SLICE, STASH []byte

func init() {
    SLICE = make([]byte, 0, 5)
}

func setSlice(slice []byte) {
    STASH = SLICE
    SLICE = slice
}

func restoreSlice() {
    SLICE = STASH
}

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

func main() {
    appendToSlice('f', 'o', 'o')
    fmt.Printf("一切正常: {'%s'}\n", SLICE)

    newSlice := make([]byte, 0, 5)
    setSlice(newSlice)

    newSlice = appendToSlice('b', 'a', 'r')
    fmt.Printf("Bar? 不! {'%s'}\n", newSlice) // <- 我需要 "bar" 出现在 newSlice 中。
    fmt.Printf("Bar 在这里: {'%s'}\n", SLICE)

    restoreSlice()
    fmt.Printf("回到原点. {'%s'}\n", SLICE)
}

输出:

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

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

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

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

Go 编程语言规范

追加和复制切片

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

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

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

示例:

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

For example,

package main

import &quot;fmt&quot;

var SLICE, STASH []byte

func init() {
	SLICE = make([]byte, 0, 5)
}

func setSlice(slice []byte) {
	STASH = SLICE
	SLICE = slice
}

func restoreSlice() {
	SLICE = STASH
}

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

func main() {
	appendToSlice(&#39;f&#39;, &#39;o&#39;, &#39;o&#39;)
	fmt.Printf(&quot;Everything is fine: {&#39;%s&#39;}\n&quot;, SLICE)

	newSlice := make([]byte, 0, 5)
	setSlice(newSlice)

	newSlice = appendToSlice(&#39;b&#39;, &#39;a&#39;, &#39;r&#39;)
	fmt.Printf(&quot;Bar? No! {&#39;%s&#39;}\n&quot;, newSlice) // &lt;- I need &quot;bar&quot; appear in newSlice.
	fmt.Printf(&quot;Bar is here: {&#39;%s&#39;}\n&quot;, SLICE)

	restoreSlice()
	fmt.Printf(&quot;Back to origin. {&#39;%s&#39;}\n&quot;, SLICE)
}

Output:

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

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

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

and

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:

确定