Go语言的字符串是一个用UTF-8编码的变宽字符序列,它的每个字符都用一个或多个字节表示 。golang
在Go语言中,没有字符类型,字符类型是rune类型,rune是int32的别称。可以使用 []byte() 获取字节,使用 []rune() 获取字符,可对中文进行转换。正则表达式
第一种,双引号,用来建立可解析的字符串字面量 (支持转义,但不能用来引用多行);数组
str := "Go语言字符串\n不能跨行赋值"
第二种,反引号,用来建立原生的字符串字面量 ,这些字符串可能由多行组成(不支持任何转义序列),原生的字符串字面量多用于书写多行消息、HTML以及正则表达式。函数
str := `Go原生原格式字符串
能够跨行`
注意:单引号不能用于定义字符串,单引号用于定义Go语言的一个特殊类型 rune,相似其余语言的byte但又不彻底同样,是指码点字面量(Unicode code point),不作任何转义的原始内容。性能
第一种,直接使用 "+" 运算符连接优化
str := "hello" + "oldboy"
golang 里面的字符串都是不可变的,每次运算都会产生一个新的字符串,因此会产生不少临时的无用的字符串,不只没有用,还会给 gc 带来额外的负担,因此性能比较差。编码
注意:链接跨行字符串时,"+" 必须在上一行末尾,不然致使编译错误。spa
str := "hello" + "oldboy" + "PythonAV" fmt.Println(str)
第二种,使用 fmt.Sprintf() 连接指针
str := fmt.Sprintf("%s,%s", "hello", "oldboy")
内部使用 []byte 实现,不像直接运算符这种会产生不少临时的字符串,可是内部的逻辑比较复杂,有不少额外的判断,还用到了 interface,因此性能也不是很好。code
第三种,使用 strings.Join() 连接
str := strings.Join([]string{"hello", "oldboy"}, ",")
join会先根据字符串数组的内容,计算出一个拼接以后的长度,而后申请对应大小的内存,一个一个字符串填入,在已有一个数组的状况下,这种效率会很高,可是原本没有,去构造这个数据的代价也不小。
第四种,使用 buffer.WriteString() 连接
var buffer bytes.Buffer buffer.WriteString("hello") buffer.WriteString(",") buffer.WriteString("oldboy") str := buffer.String()
这个比较理想,能够当成可变字符使用,对内存的增加也有优化
第一种,将字符串转换为 []rune 后调用 len 函数进行统计
str := "hello oldboy春生" length0 := len(str) length1 := len([]rune(str)) fmt.Println(length0,length1)
在 Golang 中,若是字符串中出现中文字符不能直接调用 len 函数来统计字符串字符长度,这是由于在 Go 中,字符串是以 UTF-8 为格式进行存储的,在字符串上调用 len 函数,取得的是字符串包含的 byte 的个数。
第二种,使用 bytes.Count() 统计
func Count(s, sep []byte) int
计算字节切片sep在字节切片s中非重叠显示的个数,若是 sep 为 nil,则返回 s 中的字符个数 + 1。
package main import ( "fmt" "strings" ) func main() { str := "hello oldboy春生" length := strings.Count(str, "") - 1 fmt.Println(length) }
第四种,使用 utf8.RuneCountInString() 统计
func RuneCountInString(s string) (n int)
返回 s 字符串长度,能够正常解析中文,一个中文被当作一个字符。
package main import ( "fmt" "unicode/utf8" ) func main() { str := "hello oldboy" length := utf8.RuneCountInString(str) fmt.Println(length) }
使用索引号 "[ ]" 返回子串。 返回的字符串依然指向原字节数组,仅修改了指针和长度属性。实例以下:
package main import ( "fmt" ) func main() { str := "hello, oldboy" s1 := str[0:5] s2 := str[7:13] fmt.Println(s1, s2) }
运行结果:
hello oldboy
修改字符串,可先将其转换成 []rune 或 []byte,完成后再转换为 string。不管哪一种转换,都会从新分配内存,并复制字节数组。实例以下:
package main import "fmt" func main() { str1 := "hello oldboy" s1 := []byte(str1) s1[0] = 'H' fmt.Println(string(s1)) str2 := "鸟宿池边树,僧推月下门。" s2 := []rune(str2) s2[7] = '敲' fmt.Println(string(s2)) }
运行结果:
Hello oldboy
鸟宿池边树,僧敲月下门。