Go语言 字符串(string)


什么是字符串
一个Go语言字符串是一个任意字节的常量序列。

Go语言字符串与其他语言(Java,C++,Python)字符串的不同点
Go语言中字符串的字节使用UTF-8编码表示Unicode文本,因此Go语言字符串是变宽字符序列,每一个字符都用一个或者多个字符表示,这跟其他的(C++,Java,Python 3)的字符串类型有着本质上的不同,后者为定宽字符序列。

其他语言的字符串中的单个字符可以被字节索引,而Go语言中只有在字符串只包含7位的ASCII字符(因为它们都是用一个单一的UTF-8字节表示)时才可以被字节索引。那么这是不是表示Go语言在字符串处理能力上就比其他语言弱呢?答案时否定的,应为Go语言支持一个字符一个字符的迭代,而且标准库中存在大量的字符串操作函数,最后我们还可以将Go语言的字符串转化为Unicode码点切片(类型为 [ ]rune),切片是支持直接索引的。

对于英文文本,Go使用8位来表示每一个字节,而Java或Python则需要16位或更多。采用UTF-8编码,使得Go语言无需关系机器码的排列顺序,也无需编码解码来使用其他语言。

注:每一个Unicode字符都有一个唯一的叫做“码点”的标识数字。在Go语言中,一个单一的码点在内存中以 rune 的形式表示,rune表示int32类型的别名

字面量,操作符和转义
在Go语言中,字符串字面量使用双引号 "" 或者反引号 ' 来创建。双引号用来创建可解析的字符串,支持转义,但不能用来引用多行;反引号用来创建原生的字符串字面量,可能由多行组成,但不支持转义,并且可以包含除了反引号外其他所有字符。双引号创建可解析的字符串应用最广泛,反引号用来创建原生的字符串则多用于书写多行消息,HTML以及正则表达式。
比如下面的这些例子,输出结果完全一致

text1 := "\"Hello GoLang\",I said"
text2 :=`"Hello GoLang",I said`  //这个在Java中就无法编译成功

虽然Go语言中的字符串是不可变的,但是字符串支持 + 级联操作和+=追加操作,比如下面这个例子

text1 := "Hello" + " GoLang"
text1 += " Java"
fmt.Println(text1) // 输出 Hello GoLang Java

如果底层的字符串容量不够大,不能适应添加的字符串,级联追加操作将导致底层的字符串被替换。

下面是有关字符串的一些操作符描述

text1 := "abcdefg"
fmt.Println(text1[n]) //获取字符串索引位置为n的原始字节,比如a为97
fmt.Println(text1[n:m]) //截取得字符串索引位置为 n 到 m-1 的字符串
fmt.Println(text1[n:]) //截取得字符串索引位置为 n 到 len(s)-1 的字符串
fmt.Println(text1[:m]) //截取得字符串索引位置为 0 到 m-1 的字符串
fmt.Println(len(text1)) //获取字符串的字节数
fmt.Println(utf8.RuneCountInString(text1)) //获取字符串字符的个数
fmt.Println([]rune(text1)) // 将字符串的每一个字节转换为码点值,比如这里会输出[97 98 99 100 101 102 103]
fmt.Println(string(text1[n])) // 获取字符串索引位置为n的字符值

比较字符串
Go语言中的字符串是支持常规的比较操作(<,>,==,!=,<=,>=),这些操作符会在内存中一个字节一个字节的比较,但是在执行比较操作时,常会出现以下三种问题:
①有些 Unicode 编码的字符可以用两个或者多个不同的字节序列来表示。
如果我们只关心ASCII字符,这个问题将不会存在,若是非ASCII字符,那么我们可以通过自定义标准化函数来隔离接受这些字符串。

②用户希望将不同的字符看作是相同的。
比如字符二,2,Ⅱ,②都可以看作相同的意思,那么用户输入2时,就得匹配这些相同意思的其他字符。这个也可以通过自定义标准化函数来解决。

③字符的排序跟语言的类型有关。

字符与字符串
在Go语言中,可以用rune或者int32来表示一个字符。

字符可以通过+=操作符在一个循环中往字符串末尾追加字符,但这并不是最有效的方式,我们可以使用类似Java中的StringBuilder 来实现。

var buffer bytes.Buffer  //创建一个空的 bytes.Buffer
for   {
   if piece,ok = getNextValidString();ok {
      buffer.WriteString(piece)  //通过 WriteString 方法将我们需要串联的字符串写入到 buffer 中
   }else {
      break
   }
}
fmt.Println(buffer.String())  //最后用于取回整个级联的字符串

使用 bytes.Buffer 进行字符串的累加比起+=要高效的多,尤其是在面对大数量的字符串时。

将字符串一个字符一个字符的迭代出来,可以通过 for range 循环

text1 := "abcdefg"
for index,char := range text1 {
   fmt.Printf("%d %U %c \n",index,char,char)
}

字符串索引与切片
在所有的7位ASCII字符中,通过索引提取其字符是可以的,比如下面的例子

func main() {
   text1 := "abcdefg"
   fmt.Println(string(text1[0])) //获取索引为0的字符(核心就是通过字节来转为字符,这里字节只能为一个)
}

但是对于任意字符串来讲,上面并不一定可靠,因为有些字符可能有多个字节。为了解决这个问题,我们就需要使用字符串切片,这样返回的将是一个字符而不是一个字节。

text1 := "abcdefg"
chars := []rune(text1) //先把字符串转为rune切片
for _,char := range chars { 
   fmt.Println(string(char))
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,658评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,482评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,213评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,395评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,487评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,523评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,525评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,300评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,753评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,048评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,223评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,905评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,541评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,168评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,417评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,094评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,088评论 2 352

推荐阅读更多精彩内容