【问题标题】:cannot use type []rune as type rune in append不能使用 type []rune 作为 type rune in append
【发布时间】:2015-04-22 18:55:03
【问题描述】:
package main

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

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

为什么这不起作用?如何附加lettersLowerlettersUpper

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

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

【问题讨论】:

  • 添加了关于安全附加切片的警告:与字符串不同,它们允许您改变共享内存,因此修改一个切片可以令人惊讶地改变另一个切片指向的内存。您的示例很好,但我认为这是对可能遇到此页面的任何 []rune 附加程序的有用警告。 :)

标签: go append rune


【解决方案1】:

因为append doesn't take a list to append, but rather one or more items to append。您可以在 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.

请注意,append 并不总是重新分配底层数组(这会导致性能和内存使用方面的问题)。就此示例而言,您很好,但是如果您尝试将相同的内存用于多种用途,它可能会咬您一口。一个(做作,也许不清楚)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)
}

当您尝试在将 foo 添加到其子切片后打印它时,您会得到新旧内容的奇怪混合。

如果共享底层数组存在问题,您可以使用字符串(字符串字节是不可变的,非常有效地防止意外覆盖)或像我在上面使用 append([]byte(nil), foo[:10]...) 所做的那样制作副本。

【讨论】:

  • 如果lettersLowerlettersUpper 是常量,我如何让它工作?
  • 如果它们是像const 这样的常量,它们只能是字符串,而不是[]runes,所以你必须在运行时进行转换(或者只是不让它们在第一个const地方,就像你做的那样)。但是关于切片可能是共享内存的那一点并不是要吓跑你——你的append 看起来不错——只是一个关于切片与字符串不完全一样的一般警告。
猜你喜欢
  • 1970-01-01
  • 2020-01-12
  • 2013-04-05
  • 1970-01-01
  • 2019-05-31
  • 1970-01-01
  • 2016-12-31
  • 1970-01-01
  • 2017-10-19
相关资源
最近更新 更多