Golang 中的字符串:常见错误和优秀实践

在这篇文章中,我们将讨论 Golang 中的字符串,并查看一些不同的场景,以避免常见错误 。让我们深入探讨!
1. 字符串是否可以为 nil?我们已经对 Golang 中的字符串有了基本的了解,但我们可以从 Golang 字符串不能为 nil 开始,除非您使用指向字符串的指针 。
如下代码所示,当我们创建一个字符串变量时,默认值必须是空的"" 。如果我们用 nil 值初始化字符串变量,我们将面临在变量声明中不能使用 nil 作为字符串值的错误 。例如:
func mAIn() { var s string s = nil // Cannot use 'nil' as the type string fmt.Println(s)}编译器会提示我们不能使用 nil 赋予 string 类型 。因此,我们可以只是定义变量,或者使用""作为默认值:
func main() { var s string var ss = "" fmt.Println(s, ss)}【Golang 中的字符串:常见错误和优秀实践】如果我们坚持在字符串类型变量中使用 nil 值,则应使用指针,如下所示:
func main() { var s *string fmt.Println(s)}这个时候输出则为:
<nil>但是,我们必须谨慎使用这种方法 。每次要为变量赋值时,我们都必须编写更多的代码,而且在赋新值之前还要检查是否有零值或前一个值 。
func main() { var s *string tmp := "hello" s = &tmp fmt.Printf("address: %+v, value: %s", s, *s)}这个时候打印出来 s 的地址以及所指向的值:
address: 0xc00008a030, value: hello2. 字符串是不可变的Golang 中的字符串是不可变的,这意味着我们不能更改每个字符的值 。例如:
func main() { tmp := "hello" tmp[0] = 'J' fmt.Println(tmp)}上述代码会导致编译时错误,因为无法赋值给 tmp[0]
更改字符串中单个字符的常见错误如下:
func main() { tmp := "hello" tbs := []byte(tmp) tbs[0] = 'J' fmt.Println(string(tbs)) chi := "你好" chiTBS := []byte(chi) chiTBS[0] = 'J' fmt.Println(string(chiTBS))}输出为:
JelloJ??好虽然第一个输出显示的结果符合我们的预期,但这并不是更改某个字符的正确方法 。
这是因为我们打算修改的单个部分可能存储在多个字节中,即使你想将变量转换为符文类型并更改你想要的部分,我也不得不说,这是不可能做到的,因为它可能被放置在多个符文中,我们需要谨慎行事!
3. 字符串是字节数组在 Golang 中,字符串由字节(字节的片段)组成,某些字符需要存储在多个字节中,例如:"♥" 。
因此,当需要确定一个字符串类型变量的长度时 , 我们必须谨慎编码 。例如
func main() { tmp := "¥" fmt.Println("bytes: ", len(tmp)) fmt.Println("runes: ", utf8.RuneCountInString(tmp))}len 函数返回的是字符串的字节数,而不是字符数 。当我们需要找出字符串的符文数时,可以使用 uft8.RuneCountIntString() 函数 。
另一个常见的误解是使用 uft8.RuneCountIntString() 来确定字符数,但这并不是在任何情况下都正确,因为一个字符串变量可能跨越多个符文 。请看这个例子:
func main() { tmp := "??" fmt.Println("bytes: ", len(tmp)) fmt.Println("runes: ", utf8.RuneCountInString(tmp))}输出为:
bytes:  6runes:  24. 字符串索引和forrange在 Golang 中 , 使用索引检索字符串的单个部分将为我们提供字符的 uint 值,并且只能检索第一个字节 。但在字符串变量的 for 循环中,我们可以访问每个字符的符值:
func main() { tmp := "?¥%……&*" fmt.Printf("char at 0 index, has type %T and value is %+vn", tmp[0], tmp[0]) for _, t := range tmp {  fmt.Printf("value is %+v type is %Tn", t, t) }}


推荐阅读