golang中的string尽楔、編碼

一個(gè)字符串是一個(gè)不可改變的字節(jié)序列投储。字符串可以包含任意的數(shù)據(jù),但是通常是用來(lái)包含人類(lèi)可讀的文本阔馋。

len()返回字符串字節(jié)數(shù)目(不是rune數(shù))玛荞。

通過(guò)索引可以訪問(wèn)某個(gè)字節(jié)值,0 <= index < len(str)垦缅。越界會(huì)panic冲泥。索引不是對(duì)應(yīng)的字符而是對(duì)應(yīng)的字節(jié),因?yàn)橛杏蟹茿SCII的UTF8字符有多個(gè)字節(jié)壁涎。

s := "hello, world"
fmt.Println(len(s))     // "12" 英文字符占一個(gè)字節(jié)
fmt.Println(s[0], s[7]) // "104 119" ('h' and 'w')
for range

循環(huán)是循環(huán)的字節(jié),而非字符

for i, r := range "Hello, 世界?" {
    fmt.Printf("%d\t%q\t%d\n", i, r, r)
}
0   'H' 72
1   'e' 101
2   'l' 108
3   'l' 108
4   'o' 111
5   ',' 44
6   ' ' 32
7   '世' 19990
10  '界' 30028
13  '?' 43088
第三列是字符的碼點(diǎn)志秃。

字符串截取與鏈接
fmt.Println(s[:5]) // "hello"
fmt.Println(s[7:]) // "world"
fmt.Println(s[:])  // "hello, world"
fmt.Println("hi" + s[5:]) //hi world
比較
1 字符串可以用==和<進(jìn)行比較怔球。通過(guò)逐個(gè)字節(jié)比較完成的,因此比較的結(jié)果是字符串自然編碼的順序浮还。
2 原生字符

使用`反引號(hào)括起來(lái)竟坛,沒(méi)有轉(zhuǎn)義操作。
應(yīng)用:HTML模板、JSON面值担汤、命令行提示信息等涎跨。

編碼

1 Unicode讓我們可以通過(guò)Unicode碼點(diǎn)輸入特殊的字符。有兩種形式:\uhhhh對(duì)應(yīng)16bit的碼點(diǎn)值崭歧,\Uhhhhhhhh對(duì)應(yīng)32bit的碼點(diǎn)值隅很,其中h是一個(gè)十六進(jìn)制數(shù)字,每一個(gè)對(duì)應(yīng)碼點(diǎn)的UTF8編碼率碾。以下表示相同字符:

"世界"
"\xe4\xb8\x96\xe7\x95\x8c"
"\u4e16\u754c"
"\U00004e16\U0000754c"

2 對(duì)于小于256碼點(diǎn)值可以寫(xiě)在一個(gè)十六進(jìn)制轉(zhuǎn)義字節(jié)中叔营,例如'\x41'對(duì)應(yīng)字符'A',但是對(duì)于更大的碼點(diǎn)則必須使用\u或\U轉(zhuǎn)義形式所宰。因此绒尊,'\xe4\xb8\x96'并不是一個(gè)合法的rune字符,雖然 這三個(gè)字節(jié)對(duì)應(yīng)一個(gè)有效的UTF8編碼的碼點(diǎn)仔粥。
3 字符串長(zhǎng)度用utf8.RuneCountInString(s)來(lái)獲取婴谱。

rune

1 Unicode碼點(diǎn)對(duì)應(yīng)Go語(yǔ)言中的rune整數(shù)類(lèi)型。
2 因?yàn)?rune大小一致躯泰,所以支持?jǐn)?shù)組索引和方便切割勘究。

string與[]rune轉(zhuǎn)換
r := []rune("你好 world!")
fmt.Printf("%x\n",  r) // "[4f60 597d 20 77 6f 72 6c 64 21]"
fmt.Println(string(r)) // "你好 world"
}
fmt.Println(string(65)) // "A", not "65" 整形字符串輸出為unicode碼點(diǎn)的utf8字符串。
fmt.Println(string(0x4eac)) // "京"
對(duì)字符串操作的4個(gè)包bytes斟冕、strings口糕、strconv、unicode包
  • bytes包操作[]byte磕蛇。因?yàn)樽址侵蛔x的景描,因此逐步構(gòu)創(chuàng)建字符串會(huì)導(dǎo)致很多分配和復(fù)制。使用 bytes.Buffer類(lèi)型會(huì)更高秀撇。
  • strings包提供切割超棺,索引,前綴,查找替換等功能呵燕。
  • strconv包提供了布爾型棠绘、整型數(shù)、浮點(diǎn)數(shù)和對(duì)應(yīng)字符串的相互轉(zhuǎn)換再扭,還提供了雙引號(hào)轉(zhuǎn)義相 關(guān)的轉(zhuǎn)換氧苍。
  • unicode包提供了IsDigit、IsLetter泛范、IsUpper和IsLower等類(lèi)似功能让虐,它們用于給字符分類(lèi)。
字符串與數(shù)字轉(zhuǎn)換

將一個(gè)整數(shù)轉(zhuǎn)為字符串

x := 123
fmt.Println(strconv.Itoa(x)) // "123"

將一個(gè)字符串解析為整數(shù)

x, err := strconv.Atoi("123") // x is an int
y, err := strconv.ParseInt("123", 10, 64) 

FormatInt和FormatUint函數(shù)可以用不同的進(jìn)制來(lái)格式化數(shù)字:

fmt.Println(strconv.FormatInt(int64(23), 2)) //將int64轉(zhuǎn)換成2進(jìn)制

底層原型及編碼

#runtime/string.go
type stringStruct struct {
    str unsafe.Pointer
    len int
}

從字符串定義可以看出字符串是一個(gè)結(jié)構(gòu)體罢荡,包含字符串指針和長(zhǎng)度赡突。
測(cè)試代碼見(jiàn)下方:

package main
var s string
func main()  {
    s = "123 你好 world!"
}

編譯及通過(guò)gdb查看變量s的內(nèi)存數(shù)據(jù)分布見(jiàn)圖1:

圖1

從上圖可得知字符串?dāng)?shù)字123占3個(gè)字節(jié)分別為0x31 0x32 0x33对扶。分別對(duì)應(yīng)的是ascii。

"\344\275\240\345\245\275"是8進(jìn)制表示的你好惭缰。
"0xe4 0xbd 0xa0 0xe5 0xa5 0xbd"是16進(jìn)制表示的你好浪南。

那計(jì)算機(jī)是如何識(shí)別是ascii還是unicode的呢,內(nèi)存中存儲(chǔ)的都是以字節(jié)為單元的漱受,相鄰哪幾個(gè)是組成一個(gè)漢字呢络凿?為了說(shuō)明這個(gè)問(wèn)題還是看一下上圖1以”好“這個(gè)字說(shuō)明,見(jiàn)下表格:

8進(jìn)制 345 245 275
16進(jìn)制 0xe5 0xa5 0xbd
2進(jìn)制 11100101 10100101 10111101

“好”字的依據(jù)圖2可知拜效,unicode的十六進(jìn)制值為\u597d喷众。
參考:https://www.unicode.org/charts/PDF/Unicode-5.2/U52-4E00.pdf

圖2

那如何將3個(gè)字節(jié)轉(zhuǎn)換成unicode的呢?
根據(jù)utf8編碼規(guī)則見(jiàn)圖3-go語(yǔ)言圣經(jīng)截圖:
圖3-go語(yǔ)言圣經(jīng)截圖

發(fā)現(xiàn)好字的2進(jìn)制表示正好符合1110xxxx 10xxxxxx 10xxxxxx
所以計(jì)算機(jī)識(shí)別的時(shí)候只要識(shí)別到1110且后兩個(gè)字節(jié)的前2位都是10那這3個(gè)字節(jié)組成的就表示成一個(gè)字紧憾。
具體如何將這3個(gè)字節(jié)轉(zhuǎn)換成unicode到千,有興趣的朋友可以查查。
轉(zhuǎn)換成unicode之后就可以根據(jù)unicode碼找到字體包中的字赴穗。

參考

go語(yǔ)言圣經(jīng)
【utf-8 Wikipedia】
Unicode官網(wǎng)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末憔四,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子般眉,更是在濱河造成了極大的恐慌了赵,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,548評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件甸赃,死亡現(xiàn)場(chǎng)離奇詭異柿汛,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)埠对,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,497評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)络断,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人项玛,你說(shuō)我怎么就攤上這事貌笨。” “怎么了襟沮?”我有些...
    開(kāi)封第一講書(shū)人閱讀 167,990評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵锥惋,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我开伏,道長(zhǎng)膀跌,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,618評(píng)論 1 296
  • 正文 為了忘掉前任硅则,我火速辦了婚禮淹父,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘怎虫。我一直安慰自己暑认,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,618評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布大审。 她就那樣靜靜地躺著蘸际,像睡著了一般。 火紅的嫁衣襯著肌膚如雪徒扶。 梳的紋絲不亂的頭發(fā)上粮彤,一...
    開(kāi)封第一講書(shū)人閱讀 52,246評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音姜骡,去河邊找鬼导坟。 笑死,一個(gè)胖子當(dāng)著我的面吹牛圈澈,可吹牛的內(nèi)容都是我干的惫周。 我是一名探鬼主播,決...
    沈念sama閱讀 40,819評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼康栈,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼递递!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起啥么,我...
    開(kāi)封第一講書(shū)人閱讀 39,725評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤登舞,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后悬荣,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體菠秒,經(jīng)...
    沈念sama閱讀 46,268評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,356評(píng)論 3 340
  • 正文 我和宋清朗相戀三年氯迂,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了践叠。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,488評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡囚戚,死狀恐怖酵熙,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情驰坊,我是刑警寧澤匾二,帶...
    沈念sama閱讀 36,181評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站拳芙,受9級(jí)特大地震影響察藐,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜舟扎,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,862評(píng)論 3 333
  • 文/蒙蒙 一分飞、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧睹限,春花似錦譬猫、人聲如沸讯檐。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,331評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)别洪。三九已至,卻和暖如春柳刮,著一層夾襖步出監(jiān)牢的瞬間挖垛,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,445評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工秉颗, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留痢毒,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,897評(píng)論 3 376
  • 正文 我出身青樓蚕甥,卻偏偏與公主長(zhǎng)得像哪替,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子梢灭,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,500評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容