Golang数据类型(字符串)

字符串重要概念

根据Go语言官方的定义: In Go, a string is in effect a read-only slice of bytes.
意思是Go中的字符串是一组只读的字节切片(slice of bytes),每个字符串都使用一个或多个字节表示(当字符为 ASCII 码表上的字符时占用 1 个字节,比如英文字母,其它字符根据需要占用 2-4 个字节,比如汉语、日语中的汉字、平假名、片假名等)。
  • Go中的字符串使用的是UTF-8编码
  • Go中的纯英文字符串的字节切片长度和它的字母个数完全相等,比如test这个英文单词有4个字母,那么,len("test")返回的值也为4
因为英文字母的编码为ASCII,可以用字节表示。 而其他需要用Unicode编码的语言,比如中文字符串,那么它的字节切片长度往往不会等于它的文字个数,比如"测试"这个词语虽然只包含两个汉字,但是len("测试")会返回6,因为"测"字和"试"字分别需要用3个字节来表示,总共占用6个字节

[c-alert type=“info”]那就有一个疑问了,怎么样才能让中文按字数显示长度呢?[/c-alert]

使用golang中的Rune切片(Rune Slice) 点击查看

  • Go语言中声明一个字符串变量只能用双引号""或者反勾号(backtick,‘’) 在Go中单引号只能用来声明单一字符(character),即rune

 

字符串格式化

Go语言也支持字符串格式化

format()函数以及f-strings三种方式来做字符串格式化,字符串格式化在Go中的的形式较为单一,我们可以通过fmt.Printf()配合取模运算符%来实现字符串格式化,举例如下:

var string1 string = "我是字符串1"var int_value int = 100var string2 string = "我是字符串2"var float_value1 float64 = 3.14fmt.Printf("%s %d\n", string1, int_value)fmt.Printf("%s %f\n", string2, float_value1)

 

在Go中使用取模运算符来做字符串格式化时,常见的格式码(format code)如下:

格式化输出的各种格式

  1. %v: 通用格式,将变量的默认格式输出。
  2. %T: 变量的类型。
  3. %d: 十进制整数。
  4. %b: 二进制表示的整数。
  5. %o: 八进制表示的整数。
  6. %x: 十六进制表示的整数,使用小写字母。
  7. %X: 十六进制表示的整数,使用大写字母。
  8. %s: 字符串。
  9. %q: 带有双引号的字符串。
  10. %f: 浮点数,默认精度。
  11. %e,%E: 科学计数法表示的浮点数,%e 使用小写字母,%E 使用大写字母。
  12. %g,%G: 根据实际情况选择 %e 或 %f 以产生更紧凑的(无末尾的零)输出,%g 使用小写字母,%G 使用大写字母。
  13. %t: 布尔值,true 或 false。
  14. %p: 指针,以十六进制表示。
  15. %%: 百分号本身。
其实有两种输出供我们选择

第一种,直接输出

       username := "linrux"age := 18address := "beijing"mobile := "123456777"
fmt.Printf("用户名:%s, 年龄:%d, 地址:%s, 电话:%s\r\n", username, age, address, mobile)</code></pre>

输出:

 

这种方式使用 %s、%d 等格式化占位符,通过 Printf 函数直接输出格式化后的字符串。

第二种,拼接后再输出

username := "linrux"
age := 18
address := "beijing"
mobile := "123456777"

msg := fmt.Sprintf(“用户名:%s, 年龄:%d, 地址:%s, 电话:%s\r\n”, username, age, address, mobile)
fmt.Println(msg)
输出:

 

这种方式使用 Sprintf 函数将格式化后的字符串保存在一个变量中,然后通过 Println 函数打印这个变量。

字符串的拼接

Go语言中做字符串拼接的方式很多,主要有字符串拼接符“+”、strings.Join()、bytes.Buffer、strings.Builder等四种形式来实现字符串的拼接(从严格意义上来说,上面讲到的字符串格式化也属于字符串拼接的一种),下面一一举例讲解它们的使用方法及区别:

字符串拼接符“+”

字符串拼接符“+”是最常见也是最为简单的字符串拼接方式,在Go用“+”号做拼接前需要确保做拼接的变量的数据类型为字符串,如果不是字符串,则必须用fmt.Sprint()将其转换成字符串才能完成拼接,否则系统会返回"mismatched types string and int"的异常,如下:
func main() {var string1 string = "我是字符串1"var int_value int = 100var string2 string = "我是字符串2"var float_value1 float64 = 3.14fmt.Printf(string1 + int_value)fmt.Printf(string2 + float_value1)//fmt.Printf("%s %f\n", string2, float_value1)
}
 

 

输出:

变量int_value和float_value1因为不是字符类型,所以无法连接字符串,解决方法是将变量的类型转换成字符串

func main() {var string1 string = "我是字符串1"var int_value int = 100var string2 string = "我是字符串2"var float_value1 float64 = 3.14fmt.Printf(string1 + fmt.Sprint(int_value) + "\n")fmt.Printf(string2 + fmt.Sprint(float_value1))//fmt.Printf("%s %f\n", string2, float_value1)
}

输出:

 

strings.Join()、切片、数组

在Go中,字符串实际上是一组只读长度可变的字节切片。要知道strings.Join()的用法,必须知道什么是切片(Slice),而要理解切片,又必须先要知道什么是数组(Array),所谓数组可以理解为一种特殊的列表,区别是列表可以包含多种数据类型的元素,而数组只能包含同一种数据类型的元素,即一个数组里的所有元素必须全部为字符串,或者全部为整数

在Go中,切片是数组衍生出来的概念,两者的区别是:数组的长度是固定的,在声明一个数组时,你必须指定该数组的长度(即该数组里面有多少个元素),以及该数组里元素的数据类型。而切片不同,切片的长度不是固定的,在声明一个切片时,只需指明切片里元素的数据类型即可,这里简单举例说明两者的却别:

func main() {vendor1 := [5]string{"C", "i", "s", "c", "o"}vendor2 := []string{"H", "u", "a", "w", "e", "i"}fmt.Printf("%T\n", vendor1)fmt.Printf("%T\n", vendor2)
}

输出:

 

对于切片更加详细的说明,在这里已经说

虽然切片是在数组的基础上衍生出来的数据类型,但因为切片的灵活性,实际上它在Go中的应用比数组更广泛,比如strings.Join()就必须配合切片来完成字符串的拼接,举例如下:

func main() {var vendor1 []string = []string{"C", "i", "s", "c", "o"}var vendor2 []string = []string{"H", "u", "a", "w", "e", "i"}result1 := strings.Join(vendor1, "")result2 := strings.Join(vendor2, "")fmt.Println(result1)fmt.Println(result2)
}

输出:

 

注意strings.Join(vendor1, “”)后面的""表示分隔符,这里分隔符为空,表示等下做拼接时,切片里的所有字符串元素将紧贴在一起

可以换成其他的分隔符试一下

func main() {var vendor1 []string = []string{"C", "i", "s", "c", "o"}var vendor2 []string = []string{"H", "u", "a", "w", "e", "i"}result1 := strings.Join(vendor1, ",")result2 := strings.Join(vendor2, ",")fmt.Println(result1)fmt.Println(result2)
}

输出:

 

bytes.Buffer

因为在Go中字符串实际上是一组只读、长度可变的字节切片,因此我们还可以引入Go内置的bytes标准包,通过它创建一个类型为bytes.Buffer的变量(你可以把bytes.Buffer变量理解为组成字符串的字节),然后使用它的WriteString()方法来做拼接,最后通过该变量的String()方法将它转化为字符串,即得到了拼接后的字符串内容,举例如下:
func main() {var vendor1 bytes.Buffervendor1.WriteString("l")vendor1.WriteString("i")vendor1.WriteString("n")vendor1.WriteString("r")vendor1.WriteString("u")vendor1.WriteString("x")var vendor2 bytes.Buffervendor2.WriteString("h")vendor2.WriteString("e")vendor2.WriteString("l")vendor2.WriteString("l")vendor2.WriteString("o")fmt.Println(vendor1.String())fmt.Println(vendor2.String())
}
输出:

 

这里我们通过import bytes导入了bytes这个标准包,然后创建了vendor1和vendor2两个类型为bytes.Buffer的变量,我们通过bytes.Buffer自带的WriteString()方法将字母做了拼接

注意使用bytes.Buffer来做字符串拼接可以避免生成一个新的字符串变量(比如前面讲strings.Join()时,我们额外创建了result1和result2两个变量),所有拼接的操作都是在同一个变量上完成的。

strings.Builder

上面讲到的bytes.Buffer()是通过bytes这个模块来操作字符串的拼接,这种方法多少让用户感到有些迷惑。从go1.10开始,Go语言官方在strings这个标准包里新加入了strings.Builder这个数据类型,并且官方鼓励用户在做字符串的拼接时使用strings.Builder,做字节的拼接时使用bytes.Buffer。
func main() {var vendor1 strings.Buildervendor1.WriteString("l")vendor1.WriteString("i")vendor1.WriteString("n")vendor1.WriteString("r")vendor1.WriteString("u")vendor1.WriteString("x")var vendor2 strings.Buildervendor2.WriteString("h")vendor2.WriteString("e")vendor2.WriteString("l")vendor2.WriteString("l")vendor2.WriteString("o")fmt.Println(vendor1.String())fmt.Println(vendor2.String())
}
输出:

 

可以看到,strings.Builder和bytes.Buffer的使用方法几乎一模一样,两者都是通过WriteString()来做字符串的拼接,都是通过String()来获得拼接后的字符串。不过根据Go官方的说法strings.Builder在内存使用上的性能要略优于bytes.Buffer,这里推荐大家按照官方的建议,在做字符串的拼接时使用strings.Builder,做字节的拼接时使用bytes.Buffer。

字符串的索引

在开发的过程中,有时我们需要获取字符串中的某个或者某段字符,这时就需要对字符串做索引(针对单个字符)或者切片(针对多个连续字符)。

Go语言的字符串索引号从0开始,即字符串里从左往右的第一个字符的索引号为0

在Go中,索引返回的值为byte(byte是uint8的别名,uint8的中文叫做无符号8位整数,相关的知识会在下一篇讲解整数的章节中讲到),如果你用fmt.Println(vendor1[0])会打印出字母C对应的uint8的值

func main() {vendor1 := "Linrux"fmt.Println(vendor1[0])
}

 

解决办法有两个:

1.使用%c格式码(%c格式码表示character,即字符,注意字符不等同于字符串),通过字符串格式化的方式将uint8整数转化为字符:

func main() {vendor1 := "Linrux"fmt.Printf("%c", vendor1[0])
}

输出:

2.使用string()函数将unit8整数转化为字符串:

func main() {vendor1 := "Linrux"fmt.Println(string(vendor1[0]))
}

输出:

PS:在Go中,索引号不支持使用负整数,只能使用0或正整数,否则系统会返回“invalid string index -1 (index must be non-negative)”的异常,举例如下:

func main() {vendor1 := "Linrux"fmt.Println(string(vendor1[-1]))
}

输出:

解决的方法是使用len()函数:

func main() {vendor1 := "Linrux"fmt.Println(string(vendor1[len(vendor1)-1]))
}

输出:

字符串的不可变性

作为一组字节的切片,Go语言中的字符串具有不可变性(immutability),一旦创建了一个字符串变量后,我们无法对它的内容做任何修改,哪怕一个字符,举例如下:
func main() {vendor1 := "Linrux"vendor1[0] = "s"fmt.Println(vendor1)
}
输出:

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/209012.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OpenWrt作为旁路由(网关)配置

目录 背景前提条件环境操作步骤物理层连接设置与主路由同一网段禁用IPv6取消LAN接口桥接防火墙配置 背景 本文简介如何配置OpenWrt&#xff0c;使其作为旁路由&#xff08;网关&#xff09;运行。 旁路由大概有以下这几种工作方式&#xff1a; 主路由开DHCP&#xff0c;网关未…

LeetCode刷题---反转链表

个人主页&#xff1a;元清加油_【C】,【C语言】,【数据结构与算法】-CSDN博客 个人专栏&#xff1a;http://t.csdnimg.cn/ZxuNL http://t.csdnimg.cn/c9twt 前言&#xff1a;这个专栏主要讲述递归递归、搜索与回溯算法&#xff0c;所以下面题目主要也是这些算法做的 我讲述…

XSS漏洞原理

XSS漏洞介绍&#xff1a; 跨站脚本攻击XSS(Cross Site Scripting)&#xff0c;为了不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆&#xff0c;故将跨站脚本攻击缩写为XSS。恶意攻击者往Web页面里插入恶意Script代码&#xff0c;当用户浏览该页面时&#xff0c;嵌入We…

【读书笔记】微习惯

周日晚上尝试速读一本书《微习惯》&#xff0c;共七章看了下目录结构并不复杂&#xff0c;计划每章7-8分钟读完&#xff0c; 从20:15-21:00。读的时候&#xff0c;订下闹钟&#xff0c;催促着自己的进度。边读边记了一些要点和微信读书里面的划线。 第六章实践内容最为丰富&…

CnosDB有主复制演进历程

分布式存储系统的复杂性涉及数据容灾备份、一致性、高并发请求和大容量存储等问题。本文结合CnosDB在分布式环境下的演化历程&#xff0c;分享如何将分布式理论应用于实际生产&#xff0c;以及不同实现方式的优缺点和应用场景。 分布式系统架构模式 分布式存储系统下按照数据复…

计算机网络TCP篇①

目录 一、TCP 基本信息 1.1、TCP 的头格式 1.2、什么是 TCP 1.3、什么是 TCP 连接 1.4、TCP 与 UDP 的区别 1.2、TCP 连接建立 1.2.1、TCP 三次握手的过程 1.2.2、为什么是三次握手&#xff1f;不是两次&#xff1f;四次&#xff1f;&#xff08;这个问题真是典中典&am…

C++基础 -34- 输入输出运算符重载

输出运算符重载格式 ostream & operator<<(ostream &out,person a) {cout << a.a << endl;return out; }举例输出运算符重载 #include "iostream"using namespace std;class person {public:person(int a):a(a){}int a; };ostream &…

LabVIEW在调用image.cpp或drawmgr.cpp因为DAbort而崩溃

LabVIEW在调用image.cpp或drawmgr.cpp因为DAbort而崩溃 出现下列问题&#xff0c;如何解决&#xff1f; 1. LabVIEW 程序因image.cpp或drawmgr.cpp中的错误而崩溃 2. 正在通过cRIO-9034运行独立的LabVIEW应用程序&#xff0c;但它因drawmgr.cpp中的错误而崩溃 …

什么是DDoS攻击

DDoS攻击 1. 定义2. DDoS攻击类型2.1 网络层攻击2.2 传输层攻击2.3 应用层攻击 3.DDoS攻击态势特点 1. 定义 分布式拒绝服务&#xff08;DDoS&#xff09;攻击是一种常见的网络攻击形式。攻击者利用恶意程序对一个或多个目标发起攻击&#xff0c;企图通过大规模互联网流量耗尽…

Zabbix监控接收SNMPTrap消息与SNMPTT结合

一.SNMP 协议 1.协议介绍 snmp 协议是日常使用的较多的一种协议&#xff0c;绝大多数网络设备/存储等都支持 snmp 协议&#xff0c;通过此协议可以实现设备状态的监控及管理。 2.主要组成 SNMP 协议包括以下三个部分: SNMP Agent&#xff1a;负责处理 snmp 请求&#xff0c…

Android11适配已安装应用列表

Android11适配已安装应用列表 之前做过已安装应用列表的适配&#xff0c;最近国内版SDK升级到33和隐私合规遇到很多问题&#xff0c;于是把已安装应用列表记录一下&#xff1a; 1、在Android11及以上的适配&#xff1a; package com.example.requestinsttallapplistdemoimpo…

POSTGRESQL中如何利用SQL语句快速的进行同环比?

目录 1. 引言2. 数据准备3. 时间序列数据处理4. 同比分析4.1 对两年的数据进行对比4.2 计算两年的差额和同比4.3 细分后的同比计算 5. 环比分析5.1 简单的日期环比计算5.2 先聚合再进行环比计算5.3 考虑日期不连续的环比计算 6. 性能优化技巧7. 注意事项与常见问题8. 结语 1. 引…

在Excel中,只需点击几下,就能只复制和粘贴可见单元格

你可以在Excel中隐藏列、行或单元格&#xff0c;以使数据输入或分析更容易。但是&#xff0c;当你复制并粘贴一个包含隐藏单元格的单元格区域时&#xff0c;它们会突然重新出现。 你可能没有意识到&#xff0c;但有一种方法可以只复制和粘贴Microsoft Excel中的可见单元格。只…

sql中group by和having的使用

group by&#xff1a;按照某个字段或者某些字段进行分组。 having&#xff1a;对分组之后的数据进行再次过滤&#xff0c;having必须和group by一起用&#xff0c;且在group by后面。 比如person表如下&#xff08;以下查询均基于此表&#xff09;&#xff1a; 1.group by 用法…

用Java写一个王者荣耀游戏

目录 sxt包 Background Bullet Champion ChampionDaji GameFrame GameObject Minion MinionBlue MinionRed Turret TurretBlue TurretRed beast包 Bear Beast Bird BlueBuff RedBuff Wolf Xiyi 打开Eclipse创建图片中的几个包 sxt包 Background package sxt;…

04-配置远程仓库的SSH免密登陆

配置SSH免密登录 配置步骤 创建好的远程仓库也可以使用SSH的方式进行访问,但如果没有配置公钥会有警告 第一步: 删除用户家目录下的.ssh目录,如果没有该目录或者该目录下已经有密钥了就不用执行该操作 #进入当前用户的家目录,删除.ssh 目录 LayneLAPTOP-Layne MINGW64 ~ $ r…

进行主从复制时出现的异常FATAL CONFIG FILE ERROR (Redis 6.2.6)Reading the configuration file

错误如下所示&#xff1a; FATAL CONFIG FILE ERROR (Redis 6.2.6) Reading the configuration file, at line 1 >>> include/myredis/redis.conf Bad directive or wrong number of arguments出现错误的原因是.conf文件中命令之间缺少空格&#xff0c;如下所示&…

豆粕期权 MVIX 指数构建及策略回测

1. VIX指数 VIX 最初被设计出来的目的是为了预警市场的潜在风险&#xff0c;一般来说&#xff0c;当 VIX 指数小于 15 时&#xff0c;表示市场出现非理性繁荣&#xff1b;当 VIX 指数大于 40 时&#xff0c;表示市场对 未来的非理性恐慌&#xff0c;短期内可以出现反弹。VIX 指…

非标设计之气缸概述

气缸的组成&#xff1a; 气缸的分类 单作用气缸&#xff1a; 活塞仅一侧供气&#xff0c;气压推动活塞产生推力伸出&#xff0c;靠弹簧或自重返回。 双作用气缸&#xff1a; 气缸活塞两侧都有气压力&#xff0c;来实现前进或后退动作。 气缸的缓冲 但是&#xff0c;气缸也…

matlab 基于卡尔曼滤波的GPS-INS的数据融合的导航

1、内容简介 略 25-可以交流、咨询、答疑 2、内容说明 基于卡尔曼滤波的GPS-INS的数据融合的导航 "基于卡尔曼滤波的GPS-INS的数据融合的导航 基于卡尔曼滤波实现GPS-INS组合导航系统" 卡尔曼滤波、GPS、INS、数据融合、导航 3、仿真分析 4、参考论文 略 …