英文:
Slice juggling in golang
问题
简而言之,这是一个交易:<br>
http://play.golang.org/p/ePiZcFfPZP
<hr>
如果我使用注释掉的行,一切都正常,但是没有<br>
对分配大小(cap)进行任何控制,所以切片,<br>
如果我理解正确的话,每次超过限制时都会重新分配<br>
而且它们的初始容量为零。
在setSlice()中传递newSlice的引用也不起作用。
所以,我需要一种符合Go语言习惯、优雅的方法来完成这个任务。
<hr>
提前感谢,至少感谢你的关注和时间。
<br><br>
<s>更新:
解决方法是将SLICE和STASH的类型设置为*[]byte<br>
并进行如下赋值:
var slicePtr *[]byte
tmp := make([]byte, 256)
slicePtr = &tmp // Tmp is needed because we can'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 = &tmp // Tmp is needed because we can'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')
内置函数 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 "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("Everything is fine: {'%s'}\n", SLICE)
	newSlice := make([]byte, 0, 5)
	setSlice(newSlice)
	newSlice = appendToSlice('b', 'a', 'r')
	fmt.Printf("Bar? No! {'%s'}\n", newSlice) // <- I need "bar" appear in newSlice.
	fmt.Printf("Bar is here: {'%s'}\n", SLICE)
	restoreSlice()
	fmt.Printf("Back to origin. {'%s'}\n", SLICE)
}
Output:
Everything is fine: {'foo'}
Bar? No! {'bar'}
Bar is here: {'bar'}
Back to origin. {'foo'}
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('b', 'a', 'r')
> 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' }
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论