当前位置:首页 > 科技  > 软件

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

来源: 责编: 时间:2023-10-26 17:10:41 403观看
导读在这篇文章中,我们将讨论 Golang 中的字符串,并查看一些不同的场景,以避免常见错误。让我们深入探讨!1. 字符串是否可以为 nil?我们已经对 Golang 中的字符串有了基本的了解,但我们可以从 Golang 字符串不能为 nil 开始,除非

在这篇文章中,我们将讨论 Golang 中的字符串,并查看一些不同的场景,以避免常见错误。让我们深入探讨!WhG28资讯网——每日最新资讯28at.com

WhG28资讯网——每日最新资讯28at.com

1. 字符串是否可以为 nil?

我们已经对 Golang 中的字符串有了基本的了解,但我们可以从 Golang 字符串不能为 nil 开始,除非您使用指向字符串的指针。WhG28资讯网——每日最新资讯28at.com

如下代码所示,当我们创建一个字符串变量时,默认值必须是空的""。如果我们用 nil 值初始化字符串变量,我们将面临在变量声明中不能使用 nil 作为字符串值的错误。例如:WhG28资讯网——每日最新资讯28at.com

func main() { var s string s = nil // Cannot use 'nil' as the type string fmt.Println(s)}

编译器会提示我们不能使用 nil 赋予 string 类型。因此,我们可以只是定义变量,或者使用""作为默认值:WhG28资讯网——每日最新资讯28at.com

func main() { var s string var ss = "" fmt.Println(s, ss)}

如果我们坚持在字符串类型变量中使用 nil 值,则应使用指针,如下所示:WhG28资讯网——每日最新资讯28at.com

func main() { var s *string fmt.Println(s)}

这个时候输出则为:WhG28资讯网——每日最新资讯28at.com

<nil>

但是,我们必须谨慎使用这种方法。每次要为变量赋值时,我们都必须编写更多的代码,而且在赋新值之前还要检查是否有零值或前一个值。WhG28资讯网——每日最新资讯28at.com

func main() { var s *string tmp := "hello" s = &tmp fmt.Printf("address: %+v, value: %s", s, *s)}

这个时候打印出来 s 的地址以及所指向的值:WhG28资讯网——每日最新资讯28at.com

address: 0xc00008a030, value: hello

2. 字符串是不可变的

Golang 中的字符串是不可变的,这意味着我们不能更改每个字符的值。例如:WhG28资讯网——每日最新资讯28at.com

func main() { tmp := "hello" tmp[0] = 'J' fmt.Println(tmp)}

上述代码会导致编译时错误,因为无法赋值给 tmp[0]。WhG28资讯网——每日最新资讯28at.com

更改字符串中单个字符的常见错误如下:WhG28资讯网——每日最新资讯28at.com

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))}

输出为:WhG28资讯网——每日最新资讯28at.com

JelloJ��好

虽然第一个输出显示的结果符合我们的预期,但这并不是更改某个字符的正确方法。WhG28资讯网——每日最新资讯28at.com

这是因为我们打算修改的单个部分可能存储在多个字节中,即使你想将变量转换为符文类型并更改你想要的部分,我也不得不说,这是不可能做到的,因为它可能被放置在多个符文中,我们需要谨慎行事!WhG28资讯网——每日最新资讯28at.com

3. 字符串是字节数组

在 Golang 中,字符串由字节(字节的片段)组成,某些字符需要存储在多个字节中,例如:"♥"。WhG28资讯网——每日最新资讯28at.com

因此,当需要确定一个字符串类型变量的长度时,我们必须谨慎编码。例如:WhG28资讯网——每日最新资讯28at.com

func main() { tmp := "¥" fmt.Println("bytes: ", len(tmp)) fmt.Println("runes: ", utf8.RuneCountInString(tmp))}

len 函数返回的是字符串的字节数,而不是字符数。当我们需要找出字符串的符文数时,可以使用 uft8.RuneCountIntString() 函数。WhG28资讯网——每日最新资讯28at.com

另一个常见的误解是使用 uft8.RuneCountIntString() 来确定字符数,但这并不是在任何情况下都正确,因为一个字符串变量可能跨越多个符文。请看这个例子:WhG28资讯网——每日最新资讯28at.com

func main() { tmp := "❤️" fmt.Println("bytes: ", len(tmp)) fmt.Println("runes: ", utf8.RuneCountInString(tmp))}

输出为:WhG28资讯网——每日最新资讯28at.com

bytes:  6runes:  2

4. 字符串索引和forrange

在 Golang 中,使用索引检索字符串的单个部分将为我们提供字符的 uint 值,并且只能检索第一个字节。但在字符串变量的 for 循环中,我们可以访问每个字符的符值:WhG28资讯网——每日最新资讯28at.com

func main() { tmp := "❤¥%……&*" fmt.Printf("char at 0 index, has type %T and value is %+v/n", tmp[0], tmp[0]) for _, t := range tmp {  fmt.Printf("value is %+v type is %T/n", t, t) }}

输出:WhG28资讯网——每日最新资讯28at.com

char at 0 index, has type uint8 and value is 226value is 10084 type is int32value is 65509 type is int32value is 37 type is int32value is 8230 type is int32value is 8230 type is int32value is 38 type is int32value is 42 type is int32

在对字符串进行迭代时,还要注意变量中可能存在的非 UTF8 字符,如果 Golang 无法将其理解为 UTF8,则会使用 unicode 替换而非实际值。WhG28资讯网——每日最新资讯28at.com

5. 字符串平等

在 Golang 中,我们总是可以使用 == 来检查简单的字符串是否相等,但如果我们的变量存在隐藏点,则应在比较两个字符串变量之前使用 unicode 规范包将其规范化:WhG28资讯网——每日最新资讯28at.com

func main() { cafe1 := "Café" cafe2 := "Cafe/u0301" normalizeCafe1 := norm.NFC.String(cafe1) normalizeCafe2 := norm.NFC.String(cafe2) fmt.Println(cafe1 == cafe2) fmt.Println(normalizeCafe1 == normalizeCafe2)}

6. 高效字符串构建

使用“+”连接大量字符串的效率可能非常低。使用 strings.Builder 是高效构建字符串的最佳方法之一:WhG28资讯网——每日最新资讯28at.com

func main() { sb := strings.Builder{} for i := 0; i < 1000; i++ {  sb.WriteString("hello ") } result := sb.String() fmt.Println(result)}

与传统的 + 连接方法相比,这种方法速度更快,内存消耗更少,而且可以避免创建不必要的中间字符串。我们还可以使用 bytes.Buffer 软件包来实现这一目标。WhG28资讯网——每日最新资讯28at.com

总结

  • 字符串的默认值是""
  • len 和 RuneCountIntString 函数具有不同的行为
  • 我们应该小心 for 循环和字符串
  • 字符串相等是我们需要更精确的地方

本文链接:http://www.28at.com/showinfo-26-15187-0.htmlGolang 中的字符串:常见错误和优秀实践

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: Golang中的错误处理:全面指南及示例

下一篇: 用Python实现答题卡识别!你学会了吗?

标签:
  • 热门焦点
  • 卢伟冰长文解析K60至尊版 对Redmi有着里程碑式的意义

    在今天的Redmi后性能时代战略发布会结束之后,Redmi总经理卢伟冰又带来了一篇长文,详解了为什么 Redmi 要开启后性能时代?为什么选择和 MediaTek、Pixelworks 深度合作?以及后性
  • Mate60手机壳曝光 致敬自己的经典设计

    8月3日消息,今天下午博主数码闲聊站带来了华为Mate60的第三方手机壳图,可以让我们在真机发布之前看看这款华为全新旗舰的大致轮廓。从曝光的图片看,Mate 60背后摄像头面积依然
  • Redmi Buds 4开箱简评:才199还有降噪 可以无脑入

    在上个月举办的Redmi Note11T Pro系列新机发布会上,除了两款手机新品之外,Redmi还带来了两款TWS真无线蓝牙耳机产品,Redmi Buds 4和Redmi Buds 4 Pro,此前我们在Redmi Note11T
  • 5月iOS设备性能榜:M1 M2依旧是榜单前五

    和上个月一样,没有新品发布的iOS设备性能榜的上榜设备并没有什么更替,仅仅只有跑分变化而产生的排名变动,刚刚开始的苹果WWDC2023,推出的产品也依旧是新款Mac Pro、新款Mac Stu
  • 2023 年的 Node.js 生态系统

    随着技术的不断演进和创新,Node.js 在 2023 年达到了一个新的高度。Node.js 拥有一个庞大的生态系统,可以帮助开发人员更快地实现复杂的应用。本文就来看看 Node.js 最新的生
  • 分享六款相见恨晚的PPT模版网站, 祝你做出精美的PPT!

    1、OfficePLUSOfficePLUS网站旨在为全球Office用户提供丰富的高品质原创PPT模板、实用文档、数据图表及个性化定制服务。优点:OfficePLUS是微软官方网站,囊括PPT模板、Word模
  • 如何通过Python线程池实现异步编程?

    线程池的概念和基本原理线程池是一种并发处理机制,它可以在程序启动时创建一组线程,并将它们置于等待任务的状态。当任务到达时,线程池中的某个线程会被唤醒并执行任务,执行完任
  • 2022爆款:ROG魔霸6 冰川散热系统持续护航

    喜逢开学季,各大商家开始推出自己的新产品,进行打折促销活动。对于忠实的端游爱好者来说,能够拥有一款梦寐以求的笔记本电脑是一件十分开心的事。但是现在的
  • 苹果MacBook Pro 2021测试:仍不支持平滑滚动

    据10月30日9to5 Mac 消息报道,苹果新的 14 英寸和 16 英寸 MacBook Pro 2021 上市后获得了不错的评价,亮点包括行业领先的性能,令人印象深刻的电池续航,精美丰
Top