一个Go语言字符串是一个任意字节的常量序列
go语言字符串字面量
在Go语言中,字符串字面量使用双引号 "" 或者反引号 ` 来创建。双引号用来创建可解析的字符串,支持转义,但不能用来引用多行;反引号用来创建原生的字符串字面量,可能由多行组成,但不支持转义,并且可以包含除了反引号外其他所有字符。双引号创建可解析的字符串应用最广泛,反引号用来创建原生的字符串则多用于书写多行信息,HTML以及正则表达式。
package main
import "fmt"
func main() {
var str string = "hello world"
var html string = `
<html>
<head>
<title>hello golang</title>
</head>
<html>
`
fmt.Printf("str: %v\n", str)
fmt.Printf("html: %v\n", html)
}
go语言字符串连接
1、使用加号
虽然Go语言中的字符串是不可变的,但是字符串支持 + 级联操作和 += 追加操作,例如:
package main
import "fmt"
func main() {
name := "tom"
age := "20"
msg := name + " " + age
fmt.Printf("msg: %v\n", msg) //msg: tom 20
fmt.Println("------")
msg = ""
msg += name
msg += age
fmt.Printf("msg: %v\n", msg) //msg: tom20
}
golang里面的字符串都是不可变的,每次运算都会产生一个新的字符串,所以会产生很多临时的无用的字符串,不仅没有用,还会给gc带来额外的负担,所以性能比较差
使用fmt.Sprintf()函数
package main
import (
"fmt"
)
func main() {
name := "tom"
age := "20"
msg := fmt.Sprintf("%s和%s", name, age)
fmt.Printf("msg: %v\n", msg) //msg: tom和20
}
内部使用[ ]byte实现,不像直接运算符这种会产生很多临时的字符串,但是内部逻辑比较复杂,有很多额外的判断,还用到了interface,所以性能也不是很好
使用strings.Join()
package main
import (
"fmt"
"strings"
)
func main() {
name := "tom"
age := "20"
msg := strings.Join([]string{name, age}, ",/")
fmt.Printf("msg: %v\n", msg) //msg: tom,/20
arr := []string{"乐力", "哈哈"}
strArr := strings.Join(arr, "&")
fmt.Printf("strArr: %v\n", strArr) //strArr: 乐力&哈哈
}
join会先根据字符串数组的内容,计算出一个拼接之后的长度,然后申请对应大小的内存,一个一个字符串填入,在已有一个数组的情况下,这种效率会很高,但是本来没有,去构造这个数据的代价也不小
使用buffer.WriteString()
package main
import (
"bytes"
"fmt"
)
func main() {
var buffer bytes.Buffer
buffer.WriteString("tom")
buffer.WriteString(",")
buffer.WriteString("20")
s := buffer.String()
fmt.Printf("s: %v\n", s) //s: tom,20
}
这个比较理想,可以当成可变字符使用,对内存的增长也有优化,如果能预估字符串的长度,还可以用buffer.Grow()接口来设置capacity
Go语言字符串转义字符
go语言字符串切片操作
package main
import (
"fmt"
)
func main() {
// 012345678910
str := "hello world"
n := 2
m := 7
fmt.Printf("str[n]: %c\n", str[n]) //获取字符串索引位置为 n 的原始字节
fmt.Printf("str[n:m]: %v\n", str[n:m]) //截取字符串索引位置为 n 到 m-1 的字符串
fmt.Printf("str[n:]: %v\n", str[n:]) //截取字符串索引位置为 n 到 len(s) - 1 的字符串
fmt.Printf("str[:m]: %v\n", str[:m]) //截取字符串索引位置为 0 到 m-1 的字符串
}
go语言中字符串常用函数
package main
import (
"fmt"
"strings"
)
func main() {
// 012345678910
str := "hello world AI YO WEI"
fmt.Printf("len(str): %v\n", len(str)) //len(str): 11
fmt.Printf("strings.Split(str, \"\"): %v\n", strings.Split(str, " "))
fmt.Printf("strings.Contains(str, \"hello\"): %v\n", strings.Contains(str, "hello"))
fmt.Printf("strings.ToLower(str): %v\n", strings.ToLower(str))
fmt.Printf("strings.ToUpper(str): %v\n", strings.ToUpper(str))
fmt.Printf("strings.HasPrefix(\"hello\"): %v\n", strings.HasPrefix(str, "hello"))
fmt.Printf("strings.HasSuffix(str, \"world\"): %v\n", strings.HasSuffix(str, "world"))
fmt.Printf("strings.Index(str, \"ll\"): %v\n", strings.Index(str, "ll")) //查找 ll 的位置
fmt.Printf("strings.LastIndex(str, \"I\"): %v\n", strings.LastIndex(str, "I"))
}