Go语言中的字符串

Go 中的字符串是兼容 Unicode 编码的,并且使用 UTF-8 进行编码,这样每一个Unicode字符根据代码点的大小使用1、2、3或4个字节表示代码点。
Go 语言中的字符串是一个字节切片,也就是说单个字符可以被字节索引,我们可以假定每个字符的编码只会占用一个字节。例如:

var s = "Hello world!"
for i:= 0; i < len(s); i++ {
fmt.Printf("%x ", s[i])//48 65 6c 6c 6f 20 77 6f 72 6c 64 21
}

如果是ASCII字符(用一个单一的UTF-8字节表示)(一个字节),这样做没有什么问题,若是非ASCII字符?。
对于每一个Unicode字符呢,占用的字节大小不一样,可是我们怎么知道每次取多少个字节的大小?
所以在Go语言中,我可以使用rune来解决这个问题,不管这个字符占多大的字节,都可以用一个rune来表示。
rune 是 Go 语言的内建类型,它也是 int32 的别称。在 Go 语言中,rune 表示一个代码点。

package main
import "fmt"
func main() {
var s = "Hello world!"
runes := []rune(s)
for i:= 0; i < len(runes); i++ {
fmt.Printf("%c ",runes[i])
}//H e l l o w o r l d ! } 

注:https://naveenr.net/unicode-character-set-and-utf-8-utf-16-utf-32-encoding/ 来理解一下什么是 Unicode 和 UTF-8。

字符串的构造

  • 用字节切片构造字符串
  • 用 rune 切片构造字符串

用字节切片构造字符串

byteSlice 包含字符串 Café 用 UTF-8 编码后的 16 进制字节

用字节切片构造字符串
package main
import (
"fmt"
) func main() {
byteSlice := []byte{0x43, 0x61, 0x66, 0xC3, 0xA9}
str := string(byteSlice)
fmt.Println(str)//Café
}

用 rune 切片构造字符串

 runeSlice 包含字符串 Señor的 16 进制的 Unicode 代码点

package main
import (
"fmt"
) func main() {
runeSlice := []rune{0x0053, 0x0065, 0x00f1, 0x006f, 0x0072}
str := string(runeSlice)
fmt.Println(str)//Café
}

字符串切片处理

func main() {
//字符串底层是一个byte数组,可以做切片处理
str := "hello world!"
//使用切片
slice := str[2:]
fmt.Println("slice=",slice)//slice= llo world!
}

  

字符串长度

获取字符串的字节数len(str)方法返回包含在字符串文字中的字节数。

package main
import "fmt"
func main() {
var greeting = "Hello world!" fmt.Printf("String Length is: ")
fmt.Println(len(greeting)) //String Length is : 12
}

获取字符串的字符个数:utf8 package 包中的 func RuneCountInString(s string) (n int) 方法用来获取字符串的长度。这个方法传入一个字符串参数然后返回字符串中的 rune 的数量。

package main
import (
"fmt"
"unicode/utf8"
)
func length(s string) {
fmt.Printf("length of %s is %d\n", s, utf8.RuneCountInString(s))}
func main() {
word1 := "Señor"
length(word1)//length of Señor is 5
word2 := "Pets"
length(word2)//length of Señor is 4
}

  

字符串的迭代

字符串的迭代有两种方法

package main
import (
"fmt"
)

//方法1,使用for range
func printChars1(s string) {
for index, rune := range s {
fmt.Printf("%c starts at byte %d\n", rune, index)
}
}

//方法2
func printChars2(s string) {
runes := []rune(s)
for i:= 0; i < len(runes); i++ {
fmt.Printf("%c ", runes[i])
}
} func main() {
name := "Señor"
printChars1(name)
printChars2(name)
}

输出结果:

S starts at byte 0
e starts at byte 1
ñ starts at byte 2
o starts at byte 4
r starts at byte 5
S e ñ o r

  

字符串不可变

string 是不可变的,也就说不能通过 str[0] = 'w' 方式来修改字符串。

如果需要修改字符串,可以先将 string -> []byte 或者 []rune -> 修改 -> 重写转成 string

package main

import "fmt"

func main() {
//字符串底层是一个byte数组,可以做切片处理
str := "zello world!"
arr1 := []byte(str)
arr1[0] = 'h'
str = string(arr1)
fmt.Println("str=",str) //转换成byte后,可以处理英文和数字,不能处理中文
//[]byte一个索引只能处理一个字节的数据,汉字超出范围,会出现乱码
//前面我们提到[]rune能将所有字符用一个字节表示
arr2 := []rune(str)
arr2[0] = '一'
str = string(arr2)
fmt.Println("str=",str)
}
结果:
str= hello world!
str= 一ello world!

  

连接字符串

strings包包含一个用于连接多个字符串的join()方法,其语法如下:

strings.Join(sample, " ")

Join连接数组的元素以创建单个字符串。第二个参数是分隔符,放置在数组的元素之间。

package main
import (
"fmt"
"strings"
)
func main() {
greetings := []string{"Hello","world!"}
fmt.Println(strings.Join(greetings, " "))//Hello world!
}

最新文章

  1. thinphp下拉获取更多瀑布流效果
  2. List集合特有的迭代器 ListIterator
  3. bind绑定多个事件切换
  4. Memcached存储命令 - set
  5. python virtualenv
  6. codevs3243 区间翻转
  7. UDP 构建p2p打洞过程的实现原理(持续更新)
  8. thinkphp数据库添加表单提交的数据
  9. Python3爬虫学习
  10. 如何解决MySQLAdministrator 启动报错
  11. 关于jQuery中的attr和data问题
  12. mysql共享锁与排他锁
  13. Android类似Periscope点赞效果
  14. des加密算法java&amp;c#
  15. ACM(数学问题)——UVa202:输入整数a和b(0≤a≤3000,1≤b≤3000),输出a/b的循环小数表示以及循环节长度。
  16. 基于UML的中职班主任工作管理系统的分析与设计--文献随笔(二)
  17. python调用 sshpass
  18. Java_1简介
  19. 【洛谷P3410】拍照题解(最大权闭合子图总结)
  20. 微信小程序连续动画

热门文章

  1. MySQL数据库表的设计和优化(下)
  2. linux 运维指令
  3. pod install [!] Unable to find a specification for `XXX`
  4. Ubuntu下配置LVS【h】
  5. Egret入门学习日记 --- 第九篇(书中 2.7~2.8节 内容)
  6. PL/SQL链接Oracle数据库 导出表结构和表数据
  7. jquery-easyui中改变【确认框控件的按钮文字】($.messager.confirm)
  8. linux系统中RAID10磁盘冗余阵列配置
  9. Python 图形库
  10. eclipse修改java类时不自动重启