字符串
字符串是一组的字节(byte)序列, 它是不可变的, 通常时utf-8编码.
字符串的零值是”” 不是nil.
可以len(), 不可以cap()
package main
import (
"fmt"
)
func main() {
s := "abc"
fmt.Println(len(s)) // 结果: 3
// 错误: invalid argument s (type string) for cap
// fmt.Println(cap(s))
// 错误: mismatched types string and nil
// s == nil
}
raw string
row string : 不做转义处理的字符串, 支持跨行
s := `haha\n\t` // 结果: haha\n\t
索引访问
索引访问到的是单个字符的字节(uint8类型) 字符串是byte数组。
s := "abc"
fmt.Printf("%T %v", s[0], s[0]) // 结果: uint8 97
切片子串的内部依旧指向原字节数组
package main
import (
"fmt"
"reflect"
"unsafe"
)
func main() {
s := "abc"
s1 := s[:2]
fmt.Println(s, s1)
fmt.Printf("%#v\n", (*reflect.StringHeader)(unsafe.Pointer(&s))) // 结果: &reflect.StringHeader{Data:0x4a70a0, Len:3}
fmt.Printf("%#v\n", (*reflect.StringHeader)(unsafe.Pointer(&s1))) // 结果: &reflect.StringHeader{Data:0x4a70a0, Len:2}
fmt.Printf("%#v\n", unsafe.Pointer(&s)) // 结果: (unsafe.Pointer)(0xc42000e280)
fmt.Printf("%#v\n", unsafe.Pointer(&s1)) // 结果: (unsafe.Pointer)(0xc42000e290)
fmt.Printf("%#v\n", &s1) // 结果: (*string)(0xc42000e290)
}
for遍历时, 分byte(uint8)和rune(int32)两种
package main
import (
"fmt"
)
func main() {
s := "abc"
// s[i] 是 byte
for i := range s {
fmt.Printf("%v(%T)[%c]\t", s[i], s[i], s[i])
}
fmt.Println()
// e 是 rune
for _, e := range s {
fmt.Printf("%v(%T)[%c]\t", e, e, e)
}
}
转换[]byet
使用append函数转换
package main
import (
"fmt"
)
func main() {
var bs []byte
bs = append(bs, "abc"...)
fmt.Println(bs) // 结果: [97 98 99]
}
拼接字符串
用”+”操作符拼接字符串时,每次都要重新分配内存.
当构建很大字符串时,性能就会很差,改进思路是预先分配足够的内存.使用strings.Join函数.