在这篇文章中,我们将讨论 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: hello
2. 字符串是不可变的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: 2
4. 字符串索引和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) }}
推荐阅读
- 《亮剑》中的穿帮镜头,有些离谱到让人笑掉大牙!
- 五常指的是什么意思,易经中的五常是什么意思
- 减肥中的“3多吃2少吃1不吃”,知道这些会让你轻松不少
- ps怎么做出血线,PS中的出血线该怎么样使设置
- C++中的多线程编程:一种高效的并发处理方式
- Kubernetes中的优雅关闭和零停机时间部署
- ps出血位怎么做,PS中的出血线该怎样使设置
- CDR怎么裁剪圆形,cdr中的裁剪工具要怎样使用
- 五禽戏功效,五禽戏中的熊戏是由什么构成的
- cdr中的剪切蒙版要怎样使用,ai释放剪切蒙版快捷键是什么