转义符
Go 语言的字符串常见转义符包含回车、换行、单双引号、制表符等
转义 | 含义 |
\r | 回车符(返回行首) |
\n | 换行符(直接跳到下一行的同列位置) |
\t | 制表符 |
\' | 单引号 |
\" | 双引号 |
\\ | 反斜杠 |
例如打印一个 Windows 平台下的文件路径,代码如下:
package main
import "fmt"
func main() {
fmt.Println("str := \"c:\\pprof\\main.exe\"")
}
模板字符串
Go 语言中要定义一个多行字符串时,就必须使用 ``(反引号) 字符。如果一个单行字符串包含多个双引号等时,也可以考虑使用 ``。
s1 := `第一行
第二行
第三行
`
s2 := `他说:"Go Go Go"`
fmt.Println(s1)
fmt.Println(s2)
注意:
反引号间换行将被作为字符串中的换行,但是所有的转义字符均无效,文本将原样输出。
格式化
格式化输出
Go 语言的格式化输出为 fmt.Printf()
语法:
fmt.Printf(format,val1,val2,...)
示例代码:
package main
import (
"fmt"
"strconv"
)
func main() {
username := "Tom"
age := 18
address := "北京"
mobile := "13599999999"
// 使用 Println 输出
fmt.Println("用户名:" + username + ",年龄:" + strconv.Itoa(age) + ",地址:" + address + ",电话:" + mobile)
// 使用 Printf 输出
fmt.Printf("用户名:%s,年龄:%d,地址:%s,电话:%s", username, age, address, mobile)
}
/**
输出结果:
用户名:Tom,年龄:18,地址:北京,电话:13599999999
用户名:Tom,年龄:18,地址:北京,电话:13599999999
*/
注意:
Printf 比 Println 的性能差
格式化返回
Go 语言的格式化为 fmt.Sprintf()
语法:
fmt.Sprintf(format,val1,val2,...)
示例代码:
package main
import (
"fmt"
)
func main() {
username := "Tom"
age := 18
address := "北京"
mobile := "13599999999"
message := fmt.Sprintf("用户名:%s,年龄:%d,地址:%s,电话:%s", username, age, address, mobile)
fmt.Println(message)
}
/**
输出结果:
用户名:Tom,年龄:18,地址:北京,电话:13599999999
*/
字符串拼接
Go 语言的字符串可以使用 + 或 Sprintf() 拼接。也通过 string 的 builder 进行字符串拼接,高性能。
示例代码:
func main() {
username := "Tom"
age := 18
address := "北京"
mobile := "13599999999"
var builder strings.Builder
builder.WriteString("用户名:")
builder.WriteString(username)
builder.WriteString(",年龄:")
builder.WriteString(strconv.Itoa(age))
builder.WriteString(",地址:")
builder.WriteString(address)
builder.WriteString(",电话:")
builder.WriteString(mobile)
re := builder.String()
fmt.Println(re)
}
/**
输出结果:
用户名:Tom,年龄:18,地址:北京,电话:13599999999
*/
注意:
在不考虑性能问题,推荐使用 Sprintf,考虑性能使用 strings.Builder
字符串比较
使用 ==
示例代码:
package main
import "fmt"
func main() {
srcString := "This a string"
destString := "this a string"
// 区分大小写
if srcString == destString {
fmt.Println("Equals")
} else {
fmt.Println("Not Equals")
}
// 不区分大小写
if strings.ToLower(srcString) == strings.ToLower(destString) {
fmt.Println("Equals")
} else {
fmt.Println("Not Equals")
}
}
/**
输出结果:
Not Equals
Equals
*/
使用strings.Compare
示例代码:
package main
import (
"fmt"
"strings"
)
func main() {
srcString := "This a string"
destString := "this a string"
if strings.Compare(strings.ToLower(srcString), strings.ToLower(destString)) == 0 {
fmt.Println("Equals")
} else {
fmt.Println("Not Equals")
}
}
/**
输出结果:
Equals
*/
使用 strings.EqualFold
这种方式是不区分大小写的。
示例代码:
package main
import (
"fmt"
"strings"
)
func main() {
srcString := "This a string"
destString := "this a string"
if strings.EqualFold(srcString, destString) == true {
fmt.Println("Equals")
} else {
fmt.Println("Not Equals")
}
}
/**
输出结果:
Equals
*/
常用操作
方法 | 介绍 |
len(str) | 求长度 |
+或fmt.Sprintf | 拼接字符串 |
strings.Split | 分割 |
strings.Contains | 判断是否包含 |
strings.HasPrefix,strings.HasSuffix | 前缀/后缀判断 |
strings.Index(),strings.LastIndex() | 子串出现的位置 |
strings.Join(a[]string, sep string) | join操作 |
更多的字符串操作,请参考标准库 strings 包
字符串的编码转换
字符串的编码转换是处理文本文档(比如TXT、XML、HTML等)非常常见的需求,不过可惜的是Go语言仅支持 UTF-8 和 Unicode 编码。对于其他编码,Go语言标准库并没有内置的编码转换支持。不过,所幸的是我们可以很容易基于 iconv 库用Cgo包装一个。这里有一个开源项目:GitHub - qiniu/iconv: Golang bindings to libiconv - Convert string to requested character encoding
byte和rune类型
成每个字符串的元素叫做“字符”,可以通过遍历或者单个获取字符串元素获得字符。 字符用单引号(’)包裹起来,如:
var a := '中'
var b := 'x'
Go 语言的字符有以下两种:
uint8类型,或者叫 byte 型,代表了ASCII码的一个字符。
rune类型,代表一个 UTF-8字符。
当需要处理中文、日文或者其他复合字符时,则需要用到rune类型。rune类型实际是一个int32。 Go 使用了特殊的 rune 类型来处理 Unicode,让基于 Unicode的文本处理更为方便,也可以使用 byte 型进行默认字符串处理,性能和扩展性都有照顾
// 遍历字符串
func traversalString() {
s := "pprof.cn博客"
for i := 0; i < len(s); i++ { //byte
fmt.Printf("%v(%c) ", s[i], s[i])
}
fmt.Println()
for _, r := range s { //rune
fmt.Printf("%v(%c) ", r, r)
}
fmt.Println()
}
/**
输出结果:
112(p) 112(p) 114(r) 111(o) 102(f) 46(.) 99(c) 110(n) 229(å) 141() 154() 229(å) 174(®) 162(¢)
112(p) 112(p) 114(r) 111(o) 102(f) 46(.) 99(c) 110(n) 21338(博) 23458(客)
*/
因为UTF8编码下一个中文汉字由3~4个字节组成,所以我们不能简单的按照字节去遍历一个包含中文的字符串,否则就会出现上面输出中第一行的结果。
字符串底层是一个byte数组,所以可以和[]byte类型相互转换。字符串是不能修改的 字符串是由byte字节组成,所以字符串的长度是byte字节的长度。 rune类型用来表示utf8字符,一个rune字符由一个或多个byte组成。
字符串修改
要修改字符串,需要先将其转换成[]rune或[]byte,完成后再转换为string。无论哪种转换,都会重新分配内存,并复制字节数组。
func changeString() {
s1 := "hello"
// 强制类型转换
byteS1 := []byte(s1)
byteS1[0] = 'H'
fmt.Println(string(byteS1))
s2 := "博客"
runeS2 := []rune(s2)
runeS2[0] = '狗'
fmt.Println(string(runeS2))
}