返回顶部
首页 > 资讯 > 后端开发 > GO >Golang的strings.Split()坑怎么解决
  • 587
分享到

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

2023-06-30 17:06:49 587人浏览 安东尼
摘要

这篇文章主要介绍“golang的strings.Split()坑怎么解决”,在日常操作中,相信很多人在Golang的strings.Split()坑怎么解决问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Gol

这篇文章主要介绍“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思路

    • 预先确定s 能够被切分成n

    • 创建长度为n的数组

    • 遍历 s ,将每片数据放入数组中

    • 返回

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

    您可能感兴趣的文档:

    --结束END--

    本文标题: Golang的strings.Split()坑怎么解决

    本文链接: https://lsjlt.com/news/330403.html(转载时请注明来源链接)

    有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

    猜你喜欢
    • Golang的strings.Split()坑怎么解决
      这篇文章主要介绍“Golang的strings.Split()坑怎么解决”,在日常操作中,相信很多人在Golang的strings.Split()坑怎么解决问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Gol...
      99+
      2023-06-30
    • Golang的strings.Split()踩坑记录
      目录背景场景前置排查验证打印底层信息追源码类似情况总结背景 工作中,当我们需要对字符串按照某个字符串切分成字符串数组数时,常用到strings.Split() 最近在使用过程中踩到了...
      99+
      2024-04-02
    • golang recover函数使用的坑怎么解决
      这篇文章主要讲解了“golang recover函数使用的坑怎么解决”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“golang recover函数使用的坑怎么解决”吧!一...
      99+
      2023-07-05
    • 解决Golang中ResponseWriter的一个坑
      在使用Context.ResponseWriter中的Set/WriteHeader/Write这三个方法时,使用顺序必须如下所示,否则会出现某一设置不生效的情况。 ctx.Re...
      99+
      2024-04-02
    • mybatisplus的坑怎么解决
      这篇文章主要讲解了“mybatisplus的坑怎么解决”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“mybatisplus的坑怎么解决”吧!mybatisplus的坑 insert标签ins...
      99+
      2023-06-21
    • 解决golang中container/list包中的坑
      golang中list包用法可以参看这篇文章 但是list包中大部分对于e *Element进行操作的元素都可能会导致程序崩溃,其根本原因是e是一个Element类型的指针,当然其也...
      99+
      2024-04-02
    • 怎么解决Static坑
      这篇文章主要介绍“怎么解决Static坑”,在日常操作中,相信很多人在怎么解决Static坑问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么解决Static坑”的疑惑有所帮...
      99+
      2024-04-02
    • python的ImageTk.PhotoImage坑怎么解决
      这篇文章主要介绍“python的ImageTk.PhotoImage坑怎么解决”,在日常操作中,相信很多人在python的ImageTk.PhotoImage坑怎么解决问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家...
      99+
      2023-07-04
    • mybatis的test坑怎么解决
      今天小编给大家分享一下mybatis的test坑怎么解决的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。概述mybatis使用...
      99+
      2023-07-05
    • 解决golang 关于全局变量的坑
      学习golang不久,在定义全局变量的时候遇见了坑。写个小例子,增强记忆。 错误版本 var p int func main() { p, err := test(4) if...
      99+
      2024-04-02
    • 解决Golang 中使用WaitGroup的那点坑
      sync.WaitGroup对于Golang开发者来说并不陌生,其经常作为多协程之间同步的一种机制。用好它势必会让你事半功倍,但是一旦错用将引发问题。 关于WaitGroup的使用网...
      99+
      2024-04-02
    • Golang中JSON遇到的坑如何解决
      本篇内容主要讲解“Golang中JSON遇到的坑如何解决”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Golang中JSON遇到的坑如何解决”吧!空指针会被解析成字符串"null&qu...
      99+
      2023-07-05
    • Golang解析JSON遇到的坑及解决方法
      目录写在前面空指针会被解析成字符串"null"int类型会被解析成float64写在前面 在写go的时候经常用到序列化、反序列化,记录一下遇到过的坑。 空指针会被...
      99+
      2023-02-26
      Golang解析JSON Go 解析JSON Go JSON
    • 详解Golang时间处理的踩坑及解决
      目录简介类型时区小心有坑时间解析的使用场景时间操作获取当前时间时区设置时间格式化(时间类型转字符串)时间类型转时间戳时间戳转时间类型时间字符串转时间类型时间计算获取时间类型具体内容时...
      99+
      2023-01-11
      Golang时间处理踩坑 Golang 时间处理 Go 时间处理
    • MySQL索引的坑怎么解决
      今天小编给大家分享一下MySQL索引的坑怎么解决的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下...
      99+
      2024-04-02
    • ParallelStream使用的坑怎么解决
      今天小编给大家分享一下ParallelStream使用的坑怎么解决的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。比如下面的代...
      99+
      2023-06-17
    • python中os.path.exits()的坑怎么解决
      问题有时候我们经常会看到类似的代码:assert os.path.isdir(path_model_dir) assert os.path.exits(path_model_dir)如果填写一个相对路径作为path_model_dir,那将...
      99+
      2023-05-16
      Python
    • 使用aot的坑怎么解决
      本篇内容主要讲解“使用aot的坑怎么解决”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“使用aot的坑怎么解决”吧!启动参数固定化jaotc可以通过加-J参数来指定jvm的启动参数。我们尝试使用c...
      99+
      2023-06-03
    • thinkphp6安装的坑怎么解决
      这篇文章主要介绍“thinkphp6安装的坑怎么解决”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“thinkphp6安装的坑怎么解决”文章能帮助大家解决问题。大坑==phpstudy 网站那 要关了...
      99+
      2023-06-30
    • 解决golang时间字符串转time.Time的坑
      字符串转时间一定要通过 time.ParseInLocation 不能直接用Parse todayZero, _ := time.ParseInLocation("2006-01...
      99+
      2024-04-02
    软考高级职称资格查询
    编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
    • 官方手机版

    • 微信公众号

    • 商务合作