本文始发于个人公众号:TechFlow,原创不易,求个关注

今天是golang专题的第6篇文章,这篇主要和大家聊聊golang当中的字符串的使用。

字符串定义

golang当中的字符串本质是只读的字符型数组,和C语言当中的char[]类似,但是golang为它封装了一个变量类型,叫做string。知道了string这个类型之后,我们就可以很方便地来初始化:

var str string
str1 := "hello world"
var str2 = "hello world too"

这里应该没什么难度,很好理解。由于这个数组是只读的,所以我们可以通过下标获取某一位的字符,但是不允许修改

// 允许
fmt.Println(str1[3]) // 错误
str1[3] = 'l'

这个也不是golang的独创,很多语言当中都有这个限制,因为会将字符串作为const类型存储在专门的区域。所以不允许字符串进行修改,比如Python也是如此。

除了像是数组一样,支持下标的访问之外,go中的字符串还支持拼接以及求长度的操作。我们可以用len函数获取一个字符串的长度,用+来表示字符串的拼接:

len("hello")
// 5 c := "hello" + "world"
// c="helloworld"

这些本来也属于常规操作,并不值得一提,但是关于len函数,值得仔细说说。这里有一个坑,关于utf-8编码。我们来看下面这个例子:

str := "hello 世界"
fmt.Println(len(str))

按照我们的设想,它返回的应该是8,但是实际上我们这么操作会得到12。原因很简单,因为在utf-8编码当中,一个汉字需要3个字节编码。那如果我们想要得到字符串本身的长度,而不是字符串占据的字节数,应该怎么办呢?这个时候,我们需要用到一个新的结构叫做rune,它表示单个Unicode字符。

所以我们可以将string转化成rune数组,之后再来计算长度,得到的结果就准确了。

str := "hello 世界"
fmt.Println(len([]rune(str)))

这样我们得到的结果就是8了,和我们预期一致了。如果你在使用golang的时候,需要用到utf-8编码,一定要小心。

类型转换

golang当中的字符串不像Java或者其他语言一样封装地非常完善,当我们想要将整形或者是浮点型转成字符串,或者是想要将字符串转成整形和浮点型的时候并没有方法可以直接调用,而必须要通过库函数。golang当中提供了strconv库,用来实现字符串的一些操作。

字符串转整数、浮点数

字符串转整数的方法有两个,一个是ParseInt还有一个是ParseUint,这两个方法本质上都是将字符串转成整数。区别在于前者会保留符号,后者是无符号的,用于无符号整数。

这两个函数都接受三个参数,第一个参数是要转类型的字符串,第二个参数int的进制,比如二进制、八进制还是16进制、32进制。第三个参数表示返回bit的大小,有效值为0,8,16,32,64,如果传入0就返回int或者是uint类型,如果是32,则会返回int32类型。

函数的返回值有两个,第一个是类型转换之后的结果,第二个是一个error,也就是异常类型,表示在转换的过程当中是否有出现异常。如果没有异常,那么这个值会是一个nil。我们判断异常是否是nil就知道有无错误产生,这也是golang当中判断操作有没有异常的常规做法。

所以,代码写出来会是这样的:

value, err := strconv.ParseInt("33225", 10, 32)
if err != nil {
fmt.Println("error happens")
}

如果你不想要这么多功能,就想简单一点将字符串转成int来使用,也可以通过Atoi函数。相比于ParseInt它要简单一些, 只需要传入字符串即可,它默认按照10进制进行转换,并且转换之后会返回int类型的整数。

value, err := strconv.Atoi("33234")
if err != nil {
fmt.Println("error happens")
}

字符串转浮点数只有一个函数,就是ParseFloat,由于浮点数没有进制一说,所以它只有两个参数。第一个参数是待转的字符串,第二个参数是bit的大小。和ParseInt一样,它会返回两个结果,一个是转换之后的结果,一个是error异常。

value, err := strconv.ParseFloat("33.33", 32)
if err != nil {
fmt.Println("error happens")
}

整数、浮点数转字符串

将整数和浮点数转字符串都是用Format方法,根据我们要转的类型不同,分为FormatInt和FormatFloat。FormatInt可以认为是ParseInt的逆向操作,我们固定传入一个int64的类型,和整数的进制。golang会根据我们的数字和进制,将它转成我们需要的字符串。

如果指定的进制超过10进制,那么会使用a-z字母来表示大于10的数字。

比如我们把180转成16进制,会得到b4

num := 180
fmt.Println(strconv.FormatInt(int64(num), 16))

如果我们固定要按照10进制的整数进行转换,golang还为我们提供了简化的函数Itoa,默认按照10进制转化,它等价于FormatInt(i, 10),这样我们只需要传入一个值即可。

num := 180
fmt.Println(strconv.Itoa(num))

浮点数转字符串逻辑大同小异,但是传参稍有变化。因为浮点数可以用多种方式来表示,比如科学记数法或者是十进制指数法等等。golang当中支持了这些格式,所以允许我们通过传入参数来指定我们希望得到的字符串的格式

FormatFloat接受4个参数,第一个参数就是待转换的浮点数,第二个参数表示我们希望转换之后得到的格式。一共有'f', 'b', 'e', 'E', 'g', 'G'这几种格式。

看起来有些眼花缭乱,我们仔细说说。

'f' 表示普通模式:(-ddd.dddd)

'b' 表示指数为二进制:(-ddddp±ddd)

'e' 表示十进制指数,也就是科学记数法的模式:(-d.dddde±dd)

'E' 和'e'一样,都是科学记数法的模式,只不过字母e大写:(-d.ddddE±dd)

'g' 表示指数很大时用'e'模式,否则用‘f'模式

'G' 表示指数很大时用’E'模式,否则用'f'模式

我们来看个例子:

num := 23423134.323422
fmt.Println(strconv.FormatFloat(float64(num), 'f', -1, 64))
fmt.Println(strconv.FormatFloat(float64(num), 'b', -1, 64))
fmt.Println(strconv.FormatFloat(float64(num), 'e', -1, 64))
fmt.Println(strconv.FormatFloat(float64(num), 'E', -1, 64))
fmt.Println(strconv.FormatFloat(float64(num), 'g', -1, 64))
fmt.Println(strconv.FormatFloat(float64(num), 'G', -1, 64))

得到的结果如下:

字符串和bool型转换

除了常用的整数和浮点数之外,strconv还支持与bool类型进行转换

其中将字符串转成bool类型用的是ParseBool,它只有一个参数,只接受0, 1, t, f, T, F, ture, false, True, False, TRUE, FALSE这几种取值,否则会返回错误。

flag, err := strconv.ParseBool('t')
if err != nil {
fmt.Println("error happens")
}

将bool转字符串调用FormatBool方法,它也只有一个参数,就是一个bool类型的变量,返回值也是确定的,如果是True就返回"true", 如果是False就返回"false"。

fmt.Println(strconv.FormatBool(true))

字符串运算包

前面介绍的strconv包是golang当中字符串的一个转换操作包,可以用来将字符串转成其他类型,将其他类型转化成字符串。关于字符串本身的一些操作,还有一个专门的包叫做strings

字符串比较

我们可以通过strings.Compare来比较两个字符串的大小,这个函数类似于C语言当中的strcmp,会返回一个int。

cmp := strings.Compare(str1, str2)

cmp等于-1表示str1字典序小于str2,如果str1和str2相等,cmp等于0。如果cmp=1,表示str1字典序大于str2.

查找函数

我们可以用Index函数查找一个字符串中子串的位置,它会返回第一次出现的位置,如果不存在返回-1.

var theInd = strings.Index(str, "sub")

类似的方法是LastIndex,它返回的是出现的最后一个位置,同样,如果不存在返回-1.

var theLastIdx = strings.LastIndex(str, "last")

Count和Repeat

我们可以用Count来统计子串在整体当中出现的次数。

strings.Count("abcabcabababc", "abc")

第一个参数是母串,第二个参数是子串。如果子串为空,则返回母串的长度+1.

有count自然就有重复,我们可以用Repeat方法来讲字符串重复指定的次数:

repeat := strings.Repeat("abc", 10)

Replace、Split和Join

还有Replace函数,可以替换字符串中的部分。这个函数接收四个参数,分别是字符串,匹配串和目标串,还有替换的次数。如果小于0,表示全部替换。

str := "aaaddc"

strings.Replace(str, "a", "b", 1) // baaddc
strings.Replace(str, "a", "b", -1)

我们还可以通过Split方法来分割字符串,它的使用方法和Python当中的split一样,我们传入字符串与分隔符,会返回根据分隔符分割之后的字符串数组:

str := "abc,bbc,bbd"

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

除了Split之外,我们也经常使用它的逆操作也就是Join。通过我们指定的分隔符,将一个字符串数组拼接在一起。

slice := []string{"aab", "aba", "baa"}
str := strings.Join(slice, ",")

strings当中的函数除了刚才列举的之外还有很多,比如用来去除字符串首尾多余字符的Trim和TrimLeft,判断是否包含前缀的HasPrefix和判断是否包含后缀的HasSufix等等,由于篇幅限制,不一一列举了,大家用到的时候可以查阅strings的api文档。

总结

到这里,关于golang当中string的一些基本用法就介绍完了。一般来说,我们日常需要用到的功能,strings和strconv这两个库就足够使用了。初学者可能经常会把这两个库搞混淆,其实很容易分清,strings当中封装的是操作字符串的一些函数。比如字符串判断、join、split等各种处理,而strconv是专门用来字符串和其他类型进行转换的,除此之外基本上没有其他的功能。牢记这两点之后,很容易区分开。

今天介绍的api有些多,如果记不过来也没有关系, 我们只需要大概有一个印象即可,具体可以使用到的时候再去查阅相关的资料。

如果觉得有所收获,请给我一个关注

golang基础教程——字符串篇的更多相关文章

  1. NSIS安装制作基础教程[初级篇], 献给对NSIS有兴趣的初学者

    NSIS安装制作基础教程[初级篇], 献给对NSIS有兴趣的初学者 作者: raindy 来源:http://bbs.hanzify.org/index.php?showtopic=30029 时间: ...

  2. GoLang基础数据类型--->字符串处理大全

    GoLang基础数据类型--->字符串处理大全 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 欢迎加入:   高级运维工程师之路               59843264 ...

  3. Golang基础教程

    以下使用goland的IDE演示,包含总计的golang基础功能共20个章节 一.go语言结构: 二.go基础语法: 三.变量 四.常量 五.运算符 六.条件语句 七.循环 八.函数 九.变量作用域 ...

  4. Golang基础教程——map使用篇

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是golang专题的第7篇文章,我们来聊聊golang当中map的用法. map这个数据结构我们经常使用,存储的是key-value的键 ...

  5. golang基础之三-字符串,时间,流程控制,函数

    strings和strconv的使用 strings strings.HasPrefix(s string,preffix string) bool:判断字符串s是否以prefix开头 stirngs ...

  6. Golang的基础数据类型-字符串型

    Golang的基础数据类型-字符串型 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.字符型概述 上一篇博客学习了使用单引号括起来的单个字符就是字符类型,在Golang中有两种表 ...

  7. ABP框架搭建项目系列教程基础版完结篇

    返回总目录<一步一步使用ABP框架搭建正式项目系列教程> 经过前面十二篇的基础教程,现在终于该做个总结了. 回顾 第一篇,我们建议新手朋友们先通过ABP官网的启动模板生成解决方案,因为这样 ...

  8. GeoServer基础教程(一):环境搭建篇

    转自:http://imxz.me/tech/3sdev/installation-of-geoserver.html GeoServer的是一个基于Java的软件,它允许用户查看和编辑地理空间数据, ...

  9. Qt零基础教程(四) QWidget详解篇

    在博客园里面转载我自己写的关于Qt的基础教程,没次写一篇我会在这里更新一下目录: Qt零基础教程(四) QWidget详解(1):创建一个窗口 Qt零基础教程(四) QWidget详解(2):QWid ...

随机推荐

  1. nginx日志、nginx日志切割、静态文件不记录日志和过期时间

    2019独角兽企业重金招聘Python工程师标准>>> 12.10 Nginx访问日志 日志格式 vim /usr/local/nginx/conf/nginx.conf //搜索l ...

  2. Python2 与 Python3 的区别

    python解释器默认编码(python2与python3的区别一) python2 解释器默认编码:ascii python3 解释器默认编码:utf-8 输入(python2与python3的区别 ...

  3. 聊聊select, poll 和 epoll_wait

    聊聊select, poll 和 epoll 假设项目上需要实现一个TCP的客户端和服务器从而进行跨机器的数据收发,我们很可能翻阅一些资料,然后写出如下的代码. 服务端 客户端 那么问题来了,如果有一 ...

  4. 重新认识 Spring IOC

    spring IOC 剖析 再品IOC与DI IOC(Inversion of Control) 控制反转:所谓控制反转,就是把原先我们代码里面需要实现的对象创 建.依赖的代码,反转给容器来帮忙实现. ...

  5. OpenCV 4下darknet修改

    darknet的安装使用直接在官网上获取.https://pjreddie.com/darknet/ 但我用的是OpenCV4.1.1,make时会在image_opencv.cpp中有两个错误. 1 ...

  6. A Simple Problem with Integers 循环节 修改 平方 找规律 线段树

    A Simple Problem with Integers 这个题目首先要打表找规律,这个对2018取模最后都会进入一个循环节,这个循环节的打表要用到龟兔赛跑. 龟兔赛跑算法 floyed判环算法 ...

  7. js上传文件过大导致上传失败原因以及解决办法

    背景:项目需要用到上传视频功能,由于视频有知识产权,要求必须上传到自己的服务器上不允许用第三方视频网站接口上传,于是一开始开始用的是input type=file去上传,小的视频上传没有问题,上传将近 ...

  8. Android下拉刷新SwipeRefreshLayout简单用法

    之前一直都想用下拉刷新,感觉上是庞大的工程,所以搁置了.现在学习了一下其实真的超级简单. 看了<第一行代码>以及 https://www.jianshu.com/p/3c402a9e4b7 ...

  9. vue+.netcore可支持业务代码扩展的开发框架 VOL.Vue 2.0版本发布

    框架介绍 这是一个基于vue.element-ui.iview..netcore3.1 可支持前端.后台动态扩展业务代码快速开发框架. 框架内置定制开发的代码生成器,生成的代码不需要复制也不需要更改, ...

  10. Cassandra 简介

    Cassandra是云原生和微服务化场景中最好的NoSQL数据库.我信了~ 1. Cassandra是什么 高可用性和可扩展的分布式数据库 Apache Cassandra™是一个开源分布式数据,可提 ...