Go数据-字符串(一)

字符串是不可变字节(byte)序列,其本身是一个复合结构。

type stringStruct struct {
    str unsafe.Pointer
    len int
}

1.头部指针指向字节数组,但没有null结尾。默认以UFT-8编码存储Unicode字符,字面量里允许使用十六进制、八进制和UTF编码格式。

func main() {
    s := "嘿嘿\x61\142\u0042"

    fmt.Printf("%s\n", s)
    fmt.Printf("% x, len: %d\n",s , len(s))
}

输出:

嘿嘿abB
e5 98 bf e5 98 bf 61 62 42, len: 9

内置函数len返回字节数组长度,cap不接受字符串类型参数。 字符串默认不是nil。而是""
2.使用" ` "定义不做转义处理的原始字符串,支持跨行。

func main() {
    s := `line\r\n
    lin2`

    println(s)
}

输出:

line\r\n
    lin2

3.支持!=、==、<、>、+、+=操作符.

func main() {
    s := "abcd"

    println(s == "abcd")
    println(s > "abc")
}

输出:

true
true

4.允许以索引号访问字节数组(非字符),但不能获取元素地址

func main() {
    s := "abcd"

    println(s[1])  //输出 98
    println(&s[1]) //编译报错cannot take the address of s[1]
}

5.以切片语法(起始和结束索引好)返回字串时,其内部依旧指向原字节数组。

func main() {
    s := "abcd"

    s1 := s[:3]   //从头开始仅指定结束索引位置
    s2 := s[1:4]  //指定开始和结束位置,返回[start,end]
    s3 := s[2:]   //指定开始位置,返回后面全部内容

    println(s1,s2,s3)
}

输出:

abc bcd cd

6.使用for循环遍历字符串时,分byte和rune两种方式。

func main() {
    s := "傻蛋"
    for i := 0; i < len(s); i++ {     //byte
        fmt.Printf("%d: [%c]\n", i, s[i])
    }

    for i, c := range s {            //rune: 返回数组索引号,以及Unicode字符
        fmt.Printf("%d: [%c]\n", i, c)
    }
}

输出:

0: [å]
1: [�]
2: [»]
3: [è]
4: [�]
5: [�]

0: [傻]
3: [蛋]
  1. Unicode
    类型rune专门用来存储Unicode码点(code point),它是int32的别名,相当于UCS-4/UFT-32编码格式。使用单引号的字面量,其默认值是rune。
func main() {
    r := '我'
    fmt.Printf("%T\n", r)
}

输出:

int32

8.除[ ]rune外,还可以直接在rune、string、byte间进行转换。

func main() {
    r := '我'
    s := string(r)
    b := byte(r)

    s2 := string(b)
    r2 := rune(b)

    fmt.Println(s, b, s2, r2)
}

9.可用RuneCountInString代替len返回准确的Unicode字符数量。

func main() {
    s := "哈.喽"

    println(len(s), utf8.RuneCountInString(s))
}

输出:

7  3

你可能感兴趣的:(Go数据-字符串(一))