英文:
cannot use type []rune as type rune in append
问题
包 main
var lettersLower = []rune("abcdefghijklmnopqrstuvwxyz")
var lettersUpper = []rune("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
func main() {
x := append(lettersLower, lettersUpper)
}
为什么这个代码不起作用?我该如何将 lettersLower
和 lettersUpper
进行追加?
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
答案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))
}
请注意,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))
}
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论