清水泥沙

golang基础(11.字符串和字符类型)

字符串

在go中字符串作为一个基本类型,默认使用utf8编码。当字符为ASCII码时占用一个字节,其他字符串需要2-4个自己,中文占用3个字节。

声明和初始化

var str string 
str = "test"
str2 := "test2"

获取单个字符

获取单个字符可以使用数组下标的方式

str := "test"
ch := str[0]
print(ch) // 输出t

格式化输出

还可以通过 Go 语言内置的 len() 函数获取指定字符串的长度,以及通过 fmt 包提供的 Printf 进行字符串格式化输出(用法和 PHP 中的 printf 类似)

fmt.Printf("The length of \"%s\" is %d 
", str, len(str)) 
fmt.Printf("The first character of \"%s\" is %c.
", str, ch)

转义字符

与PHP不同,go只允许使用双引号来定义字符串字面值。如果要对特定字符进行转义,可以通过 \ 实现,就像我们上面在字符串中转义双引号和换行符那样,常见的需要转义的字符如下所示:

:换行符

  • \r :回车符
  • \t :tab 键
  • \u 或 \U :Unicode 字符
  • \ :反斜杠自身

所以,上述打印代码输出结果为:

The length of "Hello world" is 11 
The first character of "Hello world" is H.

不可变值类型

在go中虽然可以通过下标的方式访问字符,但是在go中字符串作为一种不可变类型,是无法通过下标对值进行修改的。

str := "test"
str[0] = "x" //编译错误

字符编码

Go 语言中字符串默认是 UTF-8 编码的 Unicode 字符序列,所以可以包含非 ANSI 字符,比如「Hello, 学院君」可以出现在 Go 代码中。但需要注意的是,如果你的 Go 代码需要包含非 ANSI 字符,保存源文件时请注意编码格式必须选择 UTF-8。特别是在 Windows 下一般编辑器都默认存为本地编码,比如中国地区可能是 GBK 编码而不是 UTF-8,如果没注意这点在编译和运行时就会出现一些意料之外的情况。字符串的编码转换是处理文本文档(比如 TXT、XML、HTML 等)时非常常见的需求,不过 Go 语言默认仅支持 UTF-8 和 Unicode 编码,对于其他编码,Go 语言标准库并没有内置的编码转换支持。不过,所幸的是我们可以很容易基于 iconv 库包装一个。这里有一个开源项目可供参考:https://github.com/qiniu/iconv

字符串操作

字符串连接

PHP 默认提供了丰富的字符串函数对字符串进行操作,Go 也不例外,常见的操作包含连接、获取长度和指定字符,获取长度和指定字符前面已经介绍过,字符串连接只需要通过「+」即可(PHP 里面使用的是「.」):

str := "test"
str += ",test"

另外,还有一点需要注意的是如果字符串长度较长,需要换行,则「+」必须出现在上一行的末尾,否则会报错:

str := "test"+
"test2"

字符串切片

在 PHP 中我们可以通过 substr 函数获取字符串的子串,在 Go 语言中,可以通过字符串切片功能实现类似的操作,相比 substr 函数,使用起来更加方便:

package main

import "fmt"

func main() {
	str := "hello,world"
	str1 := str[:5]  //取下标五之前的数据
	str2 := str[7:]  // 取下标7后的数据
	str3 := str[1:4] // 去下标1到4前的数据

	fmt.Println(str1)
	fmt.Println(str2)
	fmt.Println(str3)
}

字符串切片和 PHP 的 substr 函数使用方式有所差异,通过「:」对字符串进行切片,冒号之前的数字代表起始点(为空表示从0开始),之后的数字代表结束点(为空表示到字符串最后),而不是子串的长度。此外 Go 字符串也支持字符串比较、是否包含指定字符/子串、获取指定子串索引位置、字符串替换、大小写转换、trim 等操作,更多操作 API,请参考标准库 strings 包。

字符串遍历

Go 语言支持两种方式遍历字符串

  • 一种是以字节数组进行遍历
package main

import "fmt"

func main() {
	str := "hello,world!我"
	n := len(str)

	for i := 0; i < n; i++ {
		ch := str[i]
		fmt.Println(i, string(ch)) // 根据下标取字符串中的字符,类型为byte
	}
}

可以看出,这个字符串长度为 14,尽管从直观上来说,这个字符串应该只有 10个字符。这是因为每个中文字符在 UTF-8 中占 3 个字节,而不是 1 个字节。

  • 另一种是以Unicode字符串遍历
package main

import "fmt"

func main() {
	str := "hello,世界"
	for i, ch := range str {
		fmt.Println(i, string(ch)) // ch 的类型为 rune
	}
}

字符类型

和 PHP 不同,Go 语言对单个字符进行了单独的类型支持,在 Go 语言中支持两个字符类型,一个是 byte(实际上是 uint8 的别名),代表 UTF-8 字符串的单个字节的值;另一个是 rune,代表单个 Unicode 字符。 关于 rune 相关的操作,可查阅 Go 标准库的 unicode 包。 另外 unicode/utf8 包也提供了 UTF-8 和 Unicode 之间的转换。出于简化语言的考虑,Go 语言的多数 API 都假设字符串为 UTF-8 编码。尽管 Unicode 字符在标准库中有支持,但实际上较少使用。