1、字符
Golang 中没有专门的 字符 类型,如果要存储单个字符(字母),一般使用 byte 来保存,且使用单引号包裹。
1 2 3 4 5 6 7 8
| var c1 byte = 'a' var c2 byte = '0' fmt.Println("c1=", c1) fmt.Println("c2=", c2) fmt.Printf("c1=%c,c2=%c\n", c1, c2)
|
贴士:
- 字符类型也可以用
d%
打印为整型
- 如果我们保存的字符在 ASCII 表的,比如
[0-1, a-z,A-Z..]
直接可以保存到 byte
- 如果我们保存的字符对应码值大于 255,这时我们可以考虑使用 int 类型保存
- 如果我们需要按照字符的方式输出,这时我们需要格式化输出,即
fmt.Printf(“%c”, c1)
- 字符可以和整型进行运算
2、字符串
传统的字符串是由字符组成的,而 Go 的字符串是由单个字节连接起来的,即 Go 字符串是一串固定长度的字符连接起来的字符序列。
字符串在 Go 中是基本类型,内容在初始化后不能修改。
Go 中的字符串都是采用 UTF-8 字符集编码,使用一对双引号 ""
或反引号 ``
定义。 ``
可以额外解析换行,即其没有字符转义功能。
1 2 3 4 5 6 7 8 9 10
| var str1 string str1 = "Hello " str2 := " World!"
fmt.Println(str1[0]) fmt.Println(len(str1)) fmt.Println(str1 + str2)
|
由于Go中的字符串不可直接改变,可以使用下列两种方式进行修改:
方式一:通过转换为字节数组[]byte
类型,构造一个临时字符串
1 2 3 4 5 6 7 8
| str := "hello"
strTemp := []byte(str) fmt.Println("strTemp=", strTemp)
strTemp[0] = 'c' strResult := string(strTemp) fmt.Println("strResult=", strResult)
|
方式二:使用切片
1 2
| str := "hello" str = "c"+ str[1:]
|
Go和Java等语言一样,字符串默认是不可变的,这样保证了线程安全,大家使用的都是只读对象,无须加锁,且能很方便的共享内存,不必使用写时复制。
3、字符串常用操作
3.1、len()
函数与字符串遍历
len()函数是go语言的内建函数,可以用来获取字符串、切片、通道等的长度。
1 2 3 4 5 6
| str1 := "hello world" str2 := "你好,"
fmt.Println(len(str1)) fmt.Println(len(str2)) fmt.Println(utf8.RuneCountInString(str2))
|
第一个函数输出11很容易理解,第二个函数却输出了9,理论上我们会认为应该是3才对。这是因为Go的字符串都是以UTF-8格式保存,每个中文占据3个字节。Go中计算UTF-8字符串格式的长度应该使用utf8.RuneCountInString
。
字符串遍历方式一:使用字节数组,注意每个中文在UTF-8中占据3个字节
1 2 3 4
| str := "hello" for i := 0; i < len(str); i++ { fmt.Println(i,str[i]) }
|
字符串遍历方式二:range关键字只是第一种遍历方式的简写
1 2 3 4
| str := "你好" for i,ch := range str { fmt.Println(i,ch) }
|
注意:由于上述 len()
函数本身原因,Unicode字符遍历需要使用range。
3.2、string()
函数类型转换
go的内建函数 string()
可以将其他类型转变为字符串类型:
1 2
| num := 12 fmt.Printf("%T \n", string(num))
|
3.3、字符串连接
使用+
能够连接字符串。但是该操作并不高效(因为字符串在Go中是基本类型,每次拼接都是拷贝了内存!)。Go1.10提供了类似 Java 的 StringBuilder 机制来进行高效字符串连接:
1 2 3 4 5 6 7 8 9 10 11 12
| str1 := "hello " str2 := " world"
var stringBuilder strings.Builder
stringBuilder.WriteString(str1) stringBuilder.WriteString(str2)
fmt.Println(stringBuilder.String())
|
在1.10版本前,可以使用 bytes.Buffer 拼接字符串(因为字符串其实是字节数组):
1 2 3
| var buf bytes.Buffer buf.WriteString("hello") fmt.Println(buf.String())
|
4、strings 包相关函数
strings 包提供了字符串的一些常见操作函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| Index(str, s string) int
Contains(str, s string) bool
Join(s []string, str string) string
Replace(str,old,new string,n int) string
Split(str,s string)[]string
Trim(s string, cutset string) string
Fields(s string) []string
|
5、strconv 包的字符串转换函数
在Java中遇到 "你好" + 123
会将 +
转变为连接符。而Go语言要求 +
号两边数据的数据类型必须一致,这使得类似的操作变得比较不便,Go提供了strconv包用于字符串与基本类型之间的转换,常用函数有Append、Format、Parse。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| str1 := make([]byte, 0, 100) str1 = strconv.AppendInt(str1, 4567, 10) str1 = strconv.AppendBool(str1, false) str1 = strconv.AppendQuote(str1, "abcdefg") str1 = strconv.AppendQuoteRune(str1, '单') fmt.Println(string(str1))
a := strconv.FormatBool(false) b := strconv.FormatFloat(123.23, 'g', 12, 64) c := strconv.FormatInt(1234, 10) d := strconv.FormatUint(12345, 10) e := strconv.Itoa(1023) fmt.Println(a, b, c, d, e)
f, _ := strconv.ParseBool("false") g, _ := strconv.ParseFloat("123.23", 64) h, _ := strconv.ParseInt("1234", 10, 64) i, _ := strconv.ParseUint("12345", 10, 64) j, _ := strconv.Atoi("1023") fmt.Println(f, g, h, i, j)
|