Golang教程:(十四)字符串
原文:https://golangbot.com/strings/ 这是本Golang系列教程的第十四篇。 string 类型单独提取为一篇教程是因为在 Go 中,string 的实现方式同其他语言的不同。 什么是字符串在 Go 中字符串是 byte 数组。可以通过将内容放在双引号 package main
import (
"fmt"
)
func main() {
name := "Hello World"
fmt.Println(name)
}
上面的[程序]输出: Go 中的字符串符合 Unicode 标准,并以 UTF-8 编码。 访问字符串中的字节因为字符串是字节数组,因此可以访问一个字符串中的字节。 package main
import (
"fmt"
)
func printBytes(s string) {
for i:= 0; i < len(s); i++ {
fmt.Printf("%x ",s[i])
}
}
func main() {
name := "Hello World"
printBytes(name)
}
在上面的程序中,len(s) 返回字符串中的字节数,我们用一个 for 循环以 16 进制打印这些字节。%x 格式化指示符用来以 16 进制打印参数。上面的程序打印: 让我们修改上面的程序以打印字符串中的字符: package main
import (
"fmt"
)
func printBytes(s string) {
for i:= 0; i < len(s); i++ {
fmt.Printf("%x ",s[i])
}
}
func printChars(s string) {
for i:= 0; i < len(s); i++ {
fmt.Printf("%c ",s[i])
}
}
func main() {
name := "Hello World"
printBytes(name)
fmt.Printf("n")
printChars(name)
}
在第 16 行的 48 65 6c 6c 6f 20 57 6f 72 6c 64
H e l l o W o r l d
虽然上面的程序看起来是一种合法的打印字符串中各个字符的方法,但是这里有一个严重的错误。让我们深入这段代码看看究竟是哪里不对。 package main
import (
"fmt"
)
func printBytes(s string) {
for i:= 0; i < len(s); i++ {
fmt.Printf("%x ",s[i])
}
}
func printChars(s string) {
for i:= 0; i < len(s); i++ {
fmt.Printf("%c ",s[i])
}
}
func main() {
name := "Hello World"
printBytes(name)
fmt.Printf("n")
printChars(name)
fmt.Printf("n")
name = "Se?or"
printBytes(name)
fmt.Printf("n")
printChars(name)
}
上面程序的输出为: 48 65 6c 6c 6f 20 57 6f 72 6c 64
H e l l o W o r l d
53 65 c3 b1 6f 72
S e ? ± o r
在上面的程序第 28 行,我们试图打印 Se?or 中的字符串,但是结果却是 S e ? ± o r,这明显是错的。为什么打印 runerune 是 Go 中的内置类型,它是 int32 的别名。在 Go 中,rune 表示一个 Unicode 码点。无论一个码点会被编码为多少个字节,它都可以表示为一个 rune。让我们修改上面的程序,使用 rune 来打印字符串中的字符。 package main
import (
"fmt"
)
func printBytes(s string) {
for i:= 0; i < len(s); i++ {
fmt.Printf("%x ",s[i])
}
}
func printChars(s string) {
runes := []rune(s)
for i:= 0; i < len(runes); i++ {
fmt.Printf("%c ",runes[i])
}
}
func main() {
name := "Hello World"
printBytes(name)
fmt.Printf("n")
printChars(name)
fmt.Printf("nn")
name = "Se?or"
printBytes(name)
fmt.Printf("n")
printChars(name)
}
在上面的程序中,第 14 行,字符串被转换为 tune 切片。然后我们遍历该切片并打印其中的字符。程序的输出如下: 48 65 6c 6c 6f 20 57 6f 72 6c 64
H e l l o W o r l d
53 65 c3 b1 6f 72
S e ? o r
上面的输出是正确的。这正是我们想要的结果。 使用 range for 遍历字符串上面的程序是遍历字符串中字符的一个正确方式。但是 Go 提供了一种更简单的方式来做到这一点:使用 range for。 package main
import (
"fmt"
)
func printCharsAndBytes(s string) {
for index,rune := range s {
fmt.Printf("%c starts at byte %dn",rune,index)
}
}
func main() {
name := "Se?or"
printCharsAndBytes(name)
}
在上面的程序中,第 8 行通过使用 range for 遍历字符串。range 返回一个 rune (在 byte 数组中)的位置,以及 rune 本身。上面的程序输出为: S starts at byte 0
e starts at byte 1
? starts at byte 2
o starts at byte 4
r starts at byte 5
从上面的输出可以看到, 通过 byte 切片创建字符串package main
import (
"fmt"
)
func main() {
byteSlice := []byte{0x43, 0x61, 0x66, 0xC3, 0xA9}
str := string(byteSlice)
fmt.Println(str)
}
在上面的程序中,byteSlice 是 如果我们换成对应的十进制数程序会正常工作吗?答案是:Yes。让我们测试一下: package main
import (
"fmt"
)
func main() {
byteSlice := []byte{67, 97, 102, 195, 169}//decimal equivalent of {'x43','x61','x66','xC3','xA9'}
str := string(byteSlice)
fmt.Println(str)
}
上面的程序同样输出: 通过 rune 切片创建字符串package main
import (
"fmt"
)
func main() {
runeSlice := []rune{0x0053, 0x0065, 0x00f1, 0x006f, 0x0072}
str := string(runeSlice)
fmt.Println(str)
}
在上面的程序中, 字符串的长度utf8 包 提供了 (译者注: package main
import (
"fmt"
"unicode/utf8"
)
func length(s string) {
fmt.Printf("length of %s is %dn",s,utf8.RuneCountInString(s))
}
func main() {
word1 := "Se?or"
length(word1)
word2 := "Pets"
length(word2)
}
上面程序的输出为: length of Se?or is 5
length of Pets is 4
字符串是不可变的在 Go 中字符串是不可变的。字符串一旦被创建就无法改变。 package main
import (
"fmt"
)
func mutate(s string)string {
s[0] = 'a'//any valid unicode character within single quote is a rune
return s
}
func main() {
h := "hello"
fmt.Println(mutate(h))
}
上面的程序中,第 8 行我们试图改变字符串的第一个字符为 为了改变一个字符串中的字符,我们需要先把字符串转换为 rune 切片,然后修改切片中的内容,最后将这个切片转换回字符串。 package main
import (
"fmt"
)
func mutate(s []rune) string {
s[0] = 'a'
return string(s)
}
func main() {
h := "hello"
fmt.Println(mutate([]rune(h)))
}
在上面的程序中,第 7 行 我已经在 github 上创建了一个单独的程序,该程序包含了所有我们讨论的内容。你可以在这里下载。 字符串的介绍到此为止。感谢阅读。 目录 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |