文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Golang的strings.Split()坑怎么解决

2023-06-30 17:24

关注

这篇文章主要介绍“Golang的strings.Split()坑怎么解决”,在日常操作中,相信很多人在Golang的strings.Split()坑怎么解决问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Golang的strings.Split()坑怎么解决”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

场景

当时是需要取某个结构体的某个属性,并将其按,切分 整体逻辑类似这样的

type Info struct{   Ids string // Ids: 123,456}func test3(info Info){   ids := info.Ids   idList := strings.Split(ids , ",")   if len(idList) < 1 {      return   }   log.Println("ids-not-empty")   // ***}

Golang的strings.Split()坑怎么解决

ids = "" 时,控制台打印了 ids-not-empty ,当时百思不得其解,按理来说应该直接走return 这个问题激发了我的好奇心,决定认真排查一下

前置

在排查之前,先大概讲讲 Go 中string的基本结构

golang的string它的运行时的数据结构位于reflect.StringHeader

type stringHeader struct {   Data unsafe.Pointer   Len  int}

其中Data指向数据数组的指针 ,Len为数组的长度

排查

验证

既然代码中的 if 判断为false,那么就实际打印一下 isList的长度看看呢

func test3(info Info){      ids := info.Ids    idList := strings.Split(ids, ",")    log.Printf("idList长度: [%d], idList: [%v]", len(idList), idList)    for index, _ := range idList {       log.Printf("idList[%d]:[%v]", index, idList[index])    }       // ***}

Golang的strings.Split()坑怎么解决

打印底层信息

好奇心加深,打印一下idsidList的信息

const (  basePrintInfoV3 = "%s 字符串的指针地址:[%v],字符串buf数组地址:[%v] ,Len字段的地址:[%p] ,Len字段值:[%v]"  basePrintInfoV2 = "%s切片的指针地址:[%p],切片数组地址:[%p], Len字段的地址:[%p], Len字段的值:[%v]")func test3(info Info) {  ids := info.Ids  idList := strings.Split(ids, ",")  getStringPtr("ids ", &ids)  getStringSliceAllPtr("idList ", &idList)  // ***}func getStringPtr(name string, str *string) {   s2 := (*reflect.StringHeader)(unsafe.Pointer(str))   log.Printf(basePrintInfoV3, name, unsafe.Pointer(str), unsafe.Pointer(s2.Data), unsafe.Pointer(&s2.Len), s2.Len)}func getStringSliceAllPtr(name string, s1 *[]string) {   s2 := (*reflect.StringHeader)(unsafe.Pointer(s1))   log.Printf(basePrintInfoV2, name, unsafe.Pointer(&s1), unsafe.Pointer(s2.Data), unsafe.Pointer(&s2.Len), s2.Len)}

Golang的strings.Split()坑怎么解决

追源码

ids 经过 split 之后的数组和预期的不一样,看来应该是 split 源码有特殊处理了,那追一下源码吧

func Split(s, sep string) []string { return genSplit(s, sep, 0, -1) }

大概读一遍源码能够理清楚genSplit思路

func genSplit(s, sep string, sepSave, n int) []string {   if n == 0 {      return nil   }   if sep == "" {      return explode(s, n)   }   if n < 0 {      // 计算 s 按照 seq 能被切成多少份      n = Count(s, sep) + 1   }   a := make([]string, n)   n--   i := 0   for i < n {      // 定位 s里的第一个 sep 所在的位置      m := Index(s, sep)      if m < 0 {         break      }      // 放入返回的数组      a[i] = s[:m+sepSave]      // 切割s      s = s[m+len(sep):]      i++   }   a[i] = s   return a[:i+1]}

那么问题应该出就出在 Count 函数中

跟进看看 count 函数会计算 s 字符串中包含了多少个 subStr

func Count(s, substr string) int {   // special case   if len(substr) == 0 {      return utf8.RuneCountInString(s) + 1   }   if len(substr) == 1 {      return bytealg.CountString(s, substr[0])   }   n := 0   for {      i := Index(s, substr)      if i == -1 {         return n      }      n++      s = s[i+len(substr):]   }}

Count 中会走 len(substr) == 1这个逻辑,其中的CountString计算s中存在多少个 substr[0],当时跟进,返回的结果是0 ,这里符合预期 。

再结合 genSplit 中的 n = Count() + 1 我们可以发现,在genSplit时,预先创建的数组长度就为0 + 1 = 1 ! 问题迎刃而解

类似情况

经过查阅,这里再总结一下其他使用strings.Split可能遇到的坑

s := strings.Split("", "")fmt.Println(s, len(s)) // [] 0 //返回空数组s = strings.Split("abc,abc", "")fmt.Println(s, len(s)) // [a b c , a b c] 7 //返回7个数组元素s = strings.Split("", ",")fmt.Println(s, len(s)) // [] 1 s = strings.Split("abc,abc", ",")fmt.Println(s, len(s)) // [abc abc] 2s = strings.Split("abc,abc", "|")fmt.Println(s, len(s)) // [abc,abc] 1fmt.Println(len("")) // 0fmt.Println(len([]string{""})) // 1 str := ""fmt.Println(str[0]) // panic

到此,关于“Golang的strings.Split()坑怎么解决”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯