12.Go 字符串

本文视频地址

内置的 string 类型。无论是字符串常量、字符串变量还是出现的字符串字面值,都被统一设置为 string。

const (
        s = “Hello"
)

func main() {
        var s1 string = “Golang"

        fmt.Printf("%T\n", s) // string
        fmt.Printf("%T\n", s1) // string
        fmt.Printf("%T\n", “Cool Golang") // string
}

Go string 类型具有如下功能特点:

string 类型的数据是不可变的
一旦声明了一个 string 类型的标识符,无论是变量还是常量,那么该标识符所指代的数据在整个程序的生命周期内便无法被更改。

func main() {    
    var s = "hello Golang"
    fmt.Println("原始值:", s)

    sl := []byte(s)
    sl[0] = 't'
    fmt.Println("切片:", string(sl))
    fmt.Println("修改后的字符串:", s)
}

原始值: hello Golang
切片: tello Golang
修改后的字符串: hello Golang

在例子中我们做了如下操作:
1 创建一个字符串
2 通过将 string 转换为一个 slice 并通过该 slice 对其内容进行修改。对 string 进行 slice 转换后,Go 编译器会为 slice 变量重新分配底层存储而不是共用 string 的底层存储,因此对 slice 的修改并未对原 string 的数据产生任何影响。

零值可用

var x string
fmt.Println(x) // x = ""
fmt.Println(len(x)) // 0

Go string 类型数据是不可变的,因此一旦有了初值后,那块数据就不会改变,其长度也不会改变。Go 将这个长度作为一个字段存储在了运行时的 string 类型结构中了。这样获取 string 长度的操作,即 len(s) 实际上就是读取存储在运行时中的那个长度值,这是一个代价极低的 O(1)操作。

支持通过+/+=操作符进行字符串连接
s := “Hello, "
s = s + “World, "
s += " Cool"

fmt.Println(s) // Hello,World, Cool

支持各种比较关系操作符:==、!= 、>=、<=、> 和 <
1 如果两个字符串的 length 不相同,那么无需比较具体字符串数据,断定两个字符串是不同的。
2 如果 length 相同,则要进一步判断数据指针是否指向同一块底层存储数据。

    如果相同,则两个字符串是等价的。
    如果不同,则还需进一步去比对实际的数据内容。

对非 ASCII 字符提供原生支持
Go 源文件的字符编码默认为 UTF-8 编码。以 UTF-8 编码作为内码存储将对应的文本存储在内存当中的。

 s := "面向加薪学习"
    rs := []rune(s)
    bs := []byte(s)
    for i, v := range rs {
        var utf8Bytes []byte
        for j := i * 3; j < (i+1)*3; j++ {
            utf8Bytes = append(utf8Bytes, bs[j])
        }
        fmt.Printf("%s => %X => %X\n", string(v), v, utf8Bytes)
    }

面 => 9762 => E99DA2
向 => 5411 => E59091
加 => 52A0 => E58AA0
薪 => 85AA => E896AA
学 => 5B66 => E5ADA6
习 => 4E60 => E4B9A0

字符串变量 s 中存储的文本是”面向加薪学习“汉字字符(非 ASCII 字符范畴),输出每个中文字符对应的 Unicode 码点,一个 rune 对应一个码点。UTF-8 编码是 Unicode 码点的一种字符编码形式,也是最常用的一种编码格式,也是 Go 默认的字符编码格式。我们还可以使用其他字符编码格式来映射 Unicode 码点,比如:UTF-16 等。
在 UTF-8 中,大多数中文字符都使用三个字节表示。[]byte(s)的转型让我们获得了 s 底层存储的底层数组,从而我们得到了每个汉字字符对应的 UTF-8 编码字节。
Go 语言直接提供了通过反引号(`)构造“所见即所得”的多行字符串的方法。

字符串的内部表示

Go string 在运行时表示为下面结构:

// $GOROOT/src/runtime/string.go
type stringStruct struct {
        str unsafe.Pointer
        len int
}

上面结构体,已经告诉我们,运行时的string它本身并不真正存储数据,而仅是由一个指向底层存储的指针和字符串的长度字段组成。

字符串的高效构造

Go 还提供了其他一些构造字符串的方法,如下:
使用 strings.Builder
使用 bytes.Buffer
使用 strings.Join
使用 fmt.Sprintf

image

你可能感兴趣的:(go)