无法将类型 []rune 作为 append 中的类型 rune 使用。

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

cannot use type []rune as type rune in append

问题

包 main

var lettersLower = []rune("abcdefghijklmnopqrstuvwxyz")
var lettersUpper = []rune("ABCDEFGHIJKLMNOPQRSTUVWXYZ")

func main() {
x := append(lettersLower, lettersUpper)
}

为什么这个代码不起作用?我该如何将 lettersLowerlettersUpper 进行追加?

prog.go:7: 无法将类型为 []rune 的 lettersUpper 用作 append 中的 rune 类型

https://play.golang.org/p/ovx_o2rKPC

英文:
package main

var lettersLower = []rune("abcdefghijklmnopqrstuvwxyz")
var lettersUpper = []rune("ABCDEFGHIJKLMNOPQRSTUVWXYZ")

func main() {
	x := append(lettersLower, lettersUpper)
}

Why does this not work? How can I append lettersLower and lettersUpper?

prog.go:7: cannot use lettersUpper (type []rune) as type rune in append

https://play.golang.org/p/ovx_o2rKPC

答案1

得分: 16

这是要翻译的内容:

这是因为append不接受要附加的列表,而是一个或多个要附加的。你可以通过在append的第二个参数上使用...来适应这个问题:

package main

import "fmt"

var lettersLower = []rune("abcdefghijklmnopqrstuvwxyz")
var lettersUpper = []rune("ABCDEFGHIJKLMNOPQRSTUVWXYZ")

func main() {
    x := append(lettersLower, lettersUpper...)
    fmt.Println(len(x))
}

在 Playground 上试一试

请注意,append并不总是重新分配底层数组(这会导致性能和内存使用方面的问题)。在这个示例中,你没有问题,但如果你尝试将同一块内存用于多个目的,可能会遇到问题。这是一个(人为的、可能不太清晰的)示例

package main

import (
    "fmt"
    "os"
)

func main() {
    foo := []byte("this is a BIG OLD TEST!!\n")
    tst := []byte("little test")
    bar := append(foo[:10], tst...)

    // 现在 bar 是正确的,但 foo 是旧文本和新文本的混合!
    fmt.Print("without copy, foo after:  ")
    os.Stdout.Write(foo)

    // 好的,现在同样的练习,但是使用 foo 的显式副本
    foo = []byte("this is a BIG OLD TEST!!\n")
    bar = append([]byte(nil), foo[:10]...) // 复制 foo[:10]
    bar = append(bar, tst...)

    // 这次我们修改了一个副本,foo 保持原样
    fmt.Print("with a copy, foo after:   ")
    os.Stdout.Write(foo)
}

当你尝试在附加到它的子切片上打印foo时,你会得到旧内容和新内容的奇怪混合。

当共享的底层数组成为问题时,你可以使用字符串(字符串字节是不可变的,可以很好地防止意外覆盖),或者像我上面使用append([]byte(nil), foo[:10]...)一样进行复制。

英文:

It's because append doesn't take a list to append, but rather one or more items to append. You can adapt to this with a ... on the second argument to append:

package main

import "fmt"

var lettersLower = []rune("abcdefghijklmnopqrstuvwxyz")
var lettersUpper = []rune("ABCDEFGHIJKLMNOPQRSTUVWXYZ")

func main() {
	x := append(lettersLower, lettersUpper...)
	fmt.Println(len(x))
}

Try it out on the Playground.

Note that append does not always re-allocate the underlying array (that would cause problems in terms of performance and memory usage). You're fine as far as this sample goes, but it may bite you if you ever try to use the same memory for multiple purposes. A (contrived, perhaps unclear) example:

package main

import (
	"fmt"
	"os"
)

func main() {
	foo := []byte("this is a BIG OLD TEST!!\n")
	tst := []byte("little test")
	bar := append(foo[:10], tst...)

    // now bar is right, but foo is a mix of old and new text!
	fmt.Print("without copy, foo after:  ")
	os.Stdout.Write(foo)

	// ok, now the same exercise but with an explicit copy of foo
	foo = []byte("this is a BIG OLD TEST!!\n")
	bar = append([]byte(nil), foo[:10]...) // copies foo[:10]
	bar = append(bar, tst...)

    // this time we modified a copy, and foo is its original self
	fmt.Print("with a copy, foo after:   ")
	os.Stdout.Write(foo)
}

When you try to print foo after appending to a subslice of it, you get a weird mix of old and new content.

Where the shared underlying array is a problem, you could either use strings (string bytes are immutable, a pretty effective guard against accidental overwrites) or make a copy as I did with append([]byte(nil), foo[:10]...) above.

huangapple
  • 本文由 发表于 2015年2月21日 07:38:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/28640097.html
匿名

发表评论

匿名网友

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

确定