go字符串
go字符串
go中字符串是一个不可改变的utf-8字符序列,类型为string。
有两点值得注意:
string可以为空(长度为0),但不会是nil。- string对象不可以修改。
string类型内部就记录了实际字符串地址和大小的数据,所以作为参数传递也是比较高效的。
和[]byte相互转换
有时为了修改字符串,或者进行数据传递解析的时候,需要string类型和[]byte类型相互进行转换。
需要注意的是,转换相当于拷贝了一遍数据,数据的修改相互不影响。
package main
import "fmt"
func main() {
str := "book"
bs := []byte(str)
bs[0] = 'l'
fmt.Println(str) // book
fmt.Println(string(bs)) // look
}
包含中文的时候字符计数
由于string类型采用utf-8字符编码,所以对于中文往往是一个字符占多个字节,如果直接用len函数只能计算字节的数量。
想要计算中文字符数可以转换为[]rune类型,一个rune变量是四个字节大小,用来存储unicode码点。
package main
import (
"fmt"
"unicode/utf8"
)
func main() {
str := "hello 中国"
fmt.Println(len(str)) // 12
fmt.Println(len([]rune(str))) // 8
// 用这个方法性能高一点
fmt.Println(utf8.RuneCountInString(str)) // 8
}
遍历字符串
可以像遍历数组和切片那样遍历整个字符串,并且遍历的时候获取到的是每个字符的unicode码,也就是rune类型的变量。可以挨个得到中文字符的值。
package main
import "fmt"
func main() {
str := "hello 中国"
for i, c := range str {
fmt.Println(i, string(c))
}
}
输出如下。
0 h
1 e
2 l
3 l
4 o
5
6 中
9 国
截取字符串
和切片和数组一样,字符串也可以通过下标截取,截取之后还是string类型。str[low:high]表示截取[low,high)范围的数据,low可以超过最大下标范围,但是high超过最大下标范围会抛出panic。
package main
import "fmt"
func main() {
str := "hello world"
sub := str[0:5]
fmt.Println(sub) // hello
}
字符串拼接优化
大部分时候直接+起来就行,可能有的情况需要拼接的字符串太多,直接+起来生成太多临时对象和拷贝,可以用string.Builder对象来拼接,提升效率。
package main
import (
"fmt"
"strings"
)
func main() {
var builder strings.Builder
builder.WriteString("hello")
builder.WriteString(" world")
fmt.Println(builder.String())
}
不区分大小写操作
可以用ToUpper和ToLower进行大小写转换,用EqualFold进行忽略大小写的比较。
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.ToUpper("Hello")) // HELLO
fmt.Println(strings.ToLower("Hello")) // hello
fmt.Println(strings.EqualFold("hello", "Hello")) // true
}
分割字符串
可以用Split函数指定分隔符来分割,但是Split不能压缩连续的分隔符,并且也不能指定多种分隔符。
package main
import (
"fmt"
"strings"
)
func main() {
strs := strings.Split("hello world", " ")
fmt.Printf("%#v\n", strs) // []string{"hello", "world"}
strs = strings.Split("hello world", " ")
fmt.Printf("%#v\n", strs) // []string{"hello", "", "world"}
}
可以用FeildsFunc函数,这样可以压缩连续的分割符,也支持多种分隔符,但是分隔符只能是字符,而不能是字符串了。
并且语义方面也有点不同,FeildsFunc会忽略长度为0的字段。
package main
import (
"fmt"
"strings"
)
func main() {
strs := strings.Split("hello world ", " ")
fmt.Printf("%#v\n", strs) // []string{"hello", "", "world", "", ""}
strs = strings.FieldsFunc("hello world ", func(c rune) bool { return c == ' ' })
fmt.Printf("%#v\n", strs) // []string{"hello", "world"}
}
浙公网安备 33010602011771号