前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >golang之旅--数据类型之字符串

golang之旅--数据类型之字符串

作者头像
李海彬
发布2018-03-27 15:05:01
1.4K0
发布2018-03-27 15:05:01
举报
文章被收录于专栏:Golang语言社区
背景

学习go已经有很长一段时间了,对于它的数据类型还没有更加深入的了解,这里做一下对数据类型的总结,第一篇是字符串的介绍。

golang中的字符串

代码语言:javascript
复制
func stringDemo() {

    str := "李阳"



    //len函数返回的是字节长度

    fmt.Println(len(str))

    //utf8的RuneCountInString判断的是ASCII长度

    fmt.Println(utf8.RuneCountInString(str))

}

字符串拼接

在java中我们拼接字符串一般怎么做?用加号拼接、用StringBuffer、用StringBuilder。相对的在go中也有好几种方法,每种方法性能不一。

通过+进行字符串拼接

在go语言中,string在内存中的存储结构是长度固定的字节数组,也就是说是字符串是不可变的。当要修改字符串的时候,需要转换为[]byte,修改完成后再转换回来。但是不论怎么转换,都必须重新分配内存,并复制数据。

代码语言:javascript
复制
func appendStrUsePlus() {

    var s1 = "Hello "

    var s2 = "World"

    s3 := s1 + s2

    fmt.Println(s3)

}



复制代码
通过加号拼接字符串,每次都必须重新分配内存。所以如果是频繁的使用+进行拼接会存在严重的性能问题。怎么解决呢? 思路是:预分配足够大的内存空间,也就是我们接下来要说的strings.Join()方法,它会统计所有参数的长度,并一次性完成内存的分配操作。
通过strings.join()进行拼接
使用strings中的方法,需要引入strings库。
func appendStrUseJoin() {

    s := make([]string, 10)

    for i := 0; i < 10; i++ {

        s[i] = "h"

    }

    fmt.Println(strings.Join(s, ","))//h,h,h,h,h,h,h,h,h,h

}

看一下string.Join()的源码,第一个参数是一个字符串数组,第二个参数是分隔符,有点类似Java中的StringUtils里的join方法。

代码语言:javascript
复制
func Join(a []string, sep string) string {

    if len(a) == 0 {

        return ""

    }

    if len(a) == 1 {

        return a[0]

    }

    n := len(sep) * (len(a) - 1)

    for i := 0; i < len(a); i++ {

        n += len(a[i])

    }



    b := make([]byte, n)

    bp := copy(b, a[0])

    for _, s := range a[1:] {

        bp += copy(b[bp:], sep)

        bp += copy(b[bp:], s)

    }

    return string(b)

}
复制代码
通过buffer进行组装拼接
使用buffer是优先创建一个缓冲区,然后向缓冲区中写入数据,类似Java中的StringBuffer。
func appendStrUseBuf() {

    var b bytes.Buffer

    b.Grow(100)



    for i := 0; i < 100; i++ {

        b.WriteString("a")

    }



    fmt.Println(b.String())

}

字符串分割

在Java中我们有StringUtils.split()方法,在go中也存在类似的方法:strings.split()。

代码语言:javascript
复制
func splitStr() {

    str := "liyang,liyang,liyang"

    strs := strings.Split(str, ",")

    fmt.Println(strs)

}

除此之外还有SplitN()、SplitAfter()、SpliteAfterN()方法,不过不是特别常用。

字符串截取

字符串实际上是一个字节数组,所以我们可以通过分片的方式来截取字符串。

字符串转字节数组

首先我们来看一段代码,之前已经提到过,字符串实际上是一个字节数组,所以我们可以像操作数组一样操作字符串的每个字节。

代码语言:javascript
复制
func strConsole() {

    str := "liyang"

    for i := 0; i < len(str); i++ {

        fmt.Println(string(str[i]))

    }

}

字符串默认值

字符串默认是是空字符串,不是nil。

代码语言:javascript
复制
func stringDefaultVal() {

var str string

fmt.Println(str == nil) //invalid operation: str == nil (mismatched types string and nil)

fmt.Println(str == "")

}

字符串存储结构

在Java中,字符串是通过char数组存储的,所以字符串是不可变的。那么在go语言中字符串是怎么存储的呢。 在go中,字符串是不可变的字节数组,其头部指针指向一个字节数组。

字符串内存分配

字符串默认在堆上分配内存存储。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2017-08-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Golang语言社区 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档