字符串

1 什么是字符串?

Go 语言中的字符串是一个字节切片。把内容放在双引号””之间,我们可以创建一个字符串。让我们来看一个创建并打印字符串的简单示例。

package main

import (
    "fmt"
)

func main() {
    name := "Hello World"
    fmt.Println(name)
}

上面的程序将会输出 Hello World

Go 中的字符串是兼容 Unicode 编码的,并且使用 UTF-8 进行编码。

 

2 获取字符串中的某个元素

字符串底层就是一个byte数组,它的使用方法和数组相同,并且可以和 []byte 类型相互转换。

package main

import "fmt"

func main() {
    var str = "hello"
    fmt.Printf("str[0]=%c length(str)=%d\n", str[0], len(str))
}

程序第7行,取字符串第0个位置的值,用法和数组相同。字符串是由byte字节组成,所以字符串的长度是byte字节的长度,一个英文字符占1个byte,因此src字符串长度为5个byte。上面的程序输出为:

str[0]=h length(str)=5

 

3 遍历字符串

由于字符串是一个字节切片,所以我们可以获取字符串的每一个字节。

package main

import (
	"fmt"
)

func testString(str string) {
    for index, val := range str {
        fmt.Printf("str[%d]=%d\n", index, val)
        //fmt.Printf("str[%d]=%c\n", index, val)
    }
}

func main() {
    name := "hello"
    testString(name)
}

我们用了一个 for 循环以打印这些字节。%d 格式限定符用于指定 ascii 码。这些打印出来的字符是 “hello”字符对应的ascii码数字。上面的程序输出:

str[0]=104
str[1]=101
str[2]=108
str[3]=108
str[4]=111

%c 格式限定符用于打印字符串的字符。这个程序输出结果是:

str[0]=h
str[1]=e
str[2]=l
str[3]=l
str[4]=o

 

4 字符串和[]byte类型相互转换

4.1 字符串转成byte类型的切片

package main

import "fmt"

func main() {
    str := "hello"
    byteSlice := []byte(str)
    fmt.Printf("%c", byteSlice)
}

上面的程序输出为:[h e l l o]

4.2 byte类型切片转为字符串

package main

import "fmt"

func main() {
    byteSlice := []byte{'h', 'e', 'l', 'l', 'o'}
    str := string(byteSlice)
    fmt.Println(str)
}

[]byte类型,元素是字符,单引号包裹。上面的程序输出为:hello

 

5 rune

rune 是 Go 语言的内建类型,它也是 int32 的别称。Go 中的字符串是兼容 Unicode 编码的,并且使用 UTF-8 进行编码。rune类型用来表示utf8字符,一个rune字符由1个或多个byte组成。在 Go 语言中,rune 表示一个代码点。代码点无论占用多少个字节,都可以用一个 rune 字符来表示。

5.1 定义rune并赋值

package main

import "fmt"

func main() {
    var b rune
    //b = 'hello'  单引号包裹的是字符,放入字符串报错
    //b = 'h'      可以赋值英文字符,utf-8中占1个字节
    b = '中'       //可以赋值中文字符,utf-8中占3个字节
    fmt.Printf("%c", b)
}

上面程序输出为:

rune类型切片与 byte类型切片的比较如下:byte是一个字节,因此中文字符放不进去,而rune可以放任意字符。

5.1 字符串转成rune类型的切片

package main

import "fmt"

func main() {
    str := "中国人民nb"
    runeSlice := []rune(str)
    fmt.Printf("%c", runeSlice)
}

 上面程序输出为:[中 国 人 民 n b]

5.2 rune类型切片转为字符串

package main

import "fmt"

func main() {
    runeSlice := []rune{'中', '国', '人', '民', 'n','b'}
    str := string(runeSlice)
    fmt.Println(str)
}

上面程序输出为:中国人民nb

 

6 字符串的长度

[utf8 package] 包中的 func RuneCountInString(s string) (n int) 方法用来获取字符串的长度。这个方法传入一个字符串参数然后返回字符串中的 rune 的数量。

package main

import (
    "fmt"
    "unicode/utf8"
)

func main() {
    str := "中国"
    fmt.Printf("length of %s is %d\n", str, utf8.RuneCountInString(str))
    fmt.Printf("length of %s is %d", str, len(str))
}

 RuneCountInString方法统计长度,返回的是字符rune字符长度,len方法统计长度,返回的是字节byte长度

上面程序输出为:

length of 中国 is 2
length of 中国 is 6

 

7 字符串是不可变的

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 行,我们试图把这个字符串中的第一个字符修改为 ‘a’。由于字符串是不可变的,因此这个操作是非法的。所以程序抛出了一个错误 main.go:8: cannot assign to s[0]

为了修改字符串,可以把字符串转化为一个 rune 切片或者byte切片。然后对这个切片可以进行任何想要的改变,最后再转化为一个字符串。

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 行,mutate 函数接收一个 rune 切片参数,它将切片的第一个元素修改为 'a',然后将 rune 切片转化为字符串,并返回该字符串。程序的第 13 行调用了该函数。我们把 h 转化为一个 rune 切片,并传递给了 mutate。这个程序输出 aello

posted @ 2022-11-17 18:11  不会钓鱼的猫  阅读(208)  评论(0编辑  收藏  举报