原创

Go 基础:字符与字符串(string)数据类型

字符与字符串

Go 内置两种字符类型:

  • 一种是 byte 的字节类类型(byteuint 的别名)
  • 另一种是表示 Unicode 编码的字符 rune。rune 在 Go 内部是 int32类型的别名,占用 4 个字节。

Go 语言默认的字符编码是 UTF-8 类型,如果需要特殊的编码转换,则使用 Unicode/UTF-8 标准包。

Go 语言将字符串作为一种原生的基本数据类型,字符串初始化可以使用 字符串字面量

  • 字面量:用于表达源代码中一个固定值的符号,源于 C 语言中的称呼,其它语言有称为常量

  • 字符串字面量(stringliteral)是指双引号引住的一系列字符,双引号中可以没有字符,可以只有一个字符,也可以有很多个字符。

字符串是不可变值类型,内部用指针指向 UTF-8 字节数组

  • 默认值是空字符串 ""
  • 可以用索引号访问字符串的字节,如 str[i]。
  • 不能用序号获取字节元素指针,如 &str[i] 是非法的。
  • 不可变类型,无法修改字节数组的值。
  • 字节数组尾部不包含 NULL。

字符串类型底层是一个二维的数据结构,一个是指针指向字节数组的起点,另一个是长度。例如:

type stringStruct struct {
    str unsafe.Pointer
    len int
}

字符串声明

所有类型声明都是一样的。

  1. 显示完整声明

    var a = "hello, word"
    
  2. 短类型声明::= 只能出现在函数内(包括方法内),只是 Go 编译器自动进行数据类型推断。

    Go 支持多个类型变量同时声明并赋值,但不建议这么使用,不易阅读

    a := "hello"
    a, b := "hello", "world"
    

字符串处理

使用索引访问字节

字符串是常量,可以通过类似数组的索引访问其字节单元,但是不能修改某个字节的
值。例

package main

import "fmt"

var a = "hello,world"

var b = "hello,世界!"

func main() {

    // 访问字符串的字节单元
    b := a[0]
    fmt.Println(b)            // 104
    fmt.Println(a[1])         // 101
    fmt.Println(string(a[2])) // l

    c := "abc"
    fmt.Println(c[0] == '\x61', c[1] == 'b') //true true
}

不做转义处理

使用 ` 定义不做转义处理的原始字符串,支持跨行

package main

import "fmt"

func main() {
    str2 := `ab\r\n\x00c`
    fmt.Println(str2)
}
// 输出结果:ab\r\n\x00c

连符串跨行连接

连符串使用 + 符号来连接,跨行连接的 + 必须在上一行的结尾,否则会报错。

package main

import "fmt"

func main() {
    str3 := "hello, " +    "world"
    fmt.Println(str3)

    str4 := "hello, " +    
        "world"
    fmt.Println(str4)
}
// 输出结果:
// hello, world
// hello, world

获取字符串子串

因字符串底层是个二维的数据结构,所以可以使用索引长度(单位:字节) 来获取字符串的子串。

注意:中文是 三个字节 表示一个汉字,如果长度不是 3 的整数倍就会显示乱码。

package main

import "fmt"

func main() {
    str5 := "hello, world"
    fmt.Println(str5[0:4]) // 指定从索引0开始, 4个字节
    fmt.Println(str5[1:]) // 索引1开始, 到结尾
    fmt.Println(str5[:4]) // 默认人0开始, 4个字节

    str6 := "中国人民共和国"
    fmt.Println(str6[0:3])
    fmt.Println(str6[3:])
    fmt.Println(str6[:6])
}
// 输出结果:
// hell
// ello, world
// hell
// 中
// 国人民共和国
// 中国

单引号表示Unicode

Go 源码采用的是 UTF-8 的编码方式,UTF-8 的字符占用的字节数可以有 1~4 个字节,Rune 字符常量使用 ''将其括住。

支持 \uFFFF、\U7FFFFFFF、\xFF 格式, 对应 rune 类型,UCS-4。

package main

import "fmt"

func main() {
    fmt.Printf("%T\n", 'a')
    var str7, str8 rune = '\u6211', '们' // 定义为 run 类型
    fmt.Println(str7 == '我', string(str8) == "\xe4\xbb\xac")
}
// 输出结果:
// int32  (rune 是 int32 的别名)
// true true

修改字符串

要修改字符串,可先将其转换成 []rune 或 []byte

package main

import "fmt"

func main() {
    str9 := "hello"
    str10 := []byte(str9) // 转换成 []byte
    str10[1] = 'H'
    fmt.Println(string(str10))

    str11 := "电脑"
    str12 := []rune(str11) // 转换成 []rune
    str12[1] = '话'
    fmt.Println(string(str12))
}
// 输出结果:
// hHllo
// 电话

循环遍历字符串

有两种方式,但都是基于 for 循环。

package main

import "fmt"

func main() {
    str13 := "hello,word"
    for i, v := range str13 {  // i 是索引,v 是值
        fmt.Println(i, string(v))
    }
    fmt.Println(".................................")
    for i := 0; i < len(str13); i++ {
        fmt.Println(i, string(str13[i]))
    }
}

strings处理

strings 是 Go 自带的字符串工具类。

判断开始字符串

strings.HasPrefix(src, dest),返回 bool

package main

import (
    "fmt"
    "strings"
)

func main() {
    str := "hello,world"

    res0 := strings.HasPrefix(str, "http")
    res01 := strings.HasPrefix(str, "hello")

    fmt.Println(res0) // false
    fmt.Println(res01) // true
}

判断结尾字符串

strings.HasPrefix(src, dest),返回 bool

package main

import (
    "fmt"
    "strings"
)

func main() {
    str := "hello,world"

    res2 := strings.HasSuffix(str, "world")
    res3 := strings.HasSuffix(str, "word")

    fmt.Println("res2 =", res2)
    fmt.Println("res3 =", res3)
}

判断字符首次出现的索引位

strings.Index(src, dest),返回 int

package main

import (
    "fmt"
    "strings"
)

func main() {
    str := "hello,world"

    num1 := strings.Index(str, "l")
    num2 := strings.Index(str, "o")
    num3 := strings.Index(str, "i")
    fmt.Println("num1 =", num1) // 2
    fmt.Println("num2 =", num2)  // 4
    fmt.Println("num3 =", num3)  // -1
}

判断字符最后出现的索引位

strings.LastIndex(src, dest),返回 int

package main

import (
    "fmt"
    "strings"
)

func main() {
    str := "hello,world"

    num4 := strings.LastIndex(str, "l")
    num5 := strings.LastIndex(str, "o")
    num6 := strings.LastIndex(str, "i")
    fmt.Println("num4 =", num4) // 9
    fmt.Println("num5 =", num5) // 7
    fmt.Println("num6 =", num6) // -1
}

字符串替换

  • Replace(s, old, new string, n int) string:指定替换次数
  • ReplaceAll(s, old, new string) string:替换所有,实际调上面的方法,n 传的是 -1,表示不限制次数。
package main

import (
    "fmt"
    "strings"
)

func main() {
    str1 := "hello,world, world"
    res5 := strings.Replace(str1, "h", "H", 1)
    res6 := strings.Replace(str1, "o", "O", 2)
    res7 := strings.ReplaceAll(str1, "l", "L")
    fmt.Println("res5 =", res5)
    fmt.Println("res6 =", res6)
    fmt.Println("res7 =", res7)
}

// 输出结果:
// Hello,world, world
// hellO,wOrld, world
// heLLo,worLd, worLd

求重复出现的次数

Count(s, substr string) int:返回整数

package main

import (
    "fmt"
    "strings"
)

func main() {
    str1 := "hello,world, world"
    fmt.Println(strings.Count(str1, "l")) // 4
    fmt.Println(strings.Count(str1, "o")) // 3
    fmt.Println(strings.Count(str1, "z")) // 0
}

重复n次返回

Repeat(s string, count int) string,返回 copy n 次的新字符串

package main

import (
    "fmt"
    "strings"
)

func main() {
    str2 := "hello,world"
    fmt.Println(strings.Repeat(str2, 1)) // hello,world
    fmt.Println(strings.Repeat(str2, 2)) // hello,worldhello,world
}

大小写转换

  • ToLower(s string) string:转小写
  • ToUpper(s string) string:转大写
package main

import (
    "fmt"
    "strings"
)

func main() {
    str2 := "Hello,World"
    fmt.Println(strings.ToLower(str2)) // hello,world
    fmt.Println(strings.ToUpper(str2)) // HELLO,WORLD
}

移除指定内容

  • Trim(s, cutset string) string:去掉首尾指定的字符
  • TrimSpace(s string) string:去掉首尾空格
  • TrimPrefix(s, prefix string) string:去掉前缀指定的字符
  • TrimSuffix(s, suffix string) string:去掉后缀指定的字符
package main

import (
    "fmt"
    "strings"
)

func main() {
    fmt.Println(strings.Trim("Hello,WorldH", "H")) // ello,World
    fmt.Println(strings.TrimSpace(" Hello,WorldH ")) //【Hello,WorldH】
    fmt.Println(strings.TrimPrefix("Hello", "H")) // ello
    fmt.Println(strings.TrimSuffix("Hello", "o")) // Hell
    fmt.Println(strings.TrimLeft("Hello", "H")) // ello
    fmt.Println(strings.TrimRight("Hello", "o")) //Hell
}

字符串切割

  • Fields(s string) []string:返回空格分隔的子串
  • Split(s, sep string) []string:指定分隔符,返回分隔的子串
package main

import (
    "fmt"
    "strings"
)

func main() {
    fmt.Println(strings.Fields("Hello World")) // [Hello World]
    fmt.Println(strings.Split("Hello Word, Word", ",")) // [Hello Word  Word]
}

字符数组拼接

  • Join(elems []string, sep string) string:传入字符串数组和连接符,返回字符串
package main

import (
    "fmt"
    "strings"
)

func main() {
    str3 := []string{"hello", "world", "best"}
    rest := strings.Join(str3, "_")
    fmt.Println(rest) // hello_world_best
}
正文到此结束
本文目录