網站首頁 編程語言 正文
介紹rune類型
golang中rune與字符串轉換的密切關系
rune
?類型是 Go 語言的一種特殊數字類型。在?builtin/builtin.go
?文件中,它的定義是type rune = int32
.官方對它是這么解釋的:rune
?是類型?int32
?的別名,在所有方面都等價于它,用來區分字符值跟整數值.使用單引號定義 ,返回采用 UTF-8 編碼的 Unicode 碼點.Go 語言通過?rune
?處理中文,支持國際化多語言。
為什么要給int32取一個別名rune呢,為什么不直接使用int32?
這是因為別名的使用在大型項目重構中作用最為明顯,它能解決代碼升級或遷移過程中可能存在的類型兼容性問題。在go語言中還有另外一個類型別名也是用來處理字符的,要知道在go語言中可沒有char這個類型,因此對于字符的處理就要特別對待。
rune如何處理字符?
rune主要表示字符碼點,特別在處理中文方面尤其有效。下面是例子
func main() { s := "我是一個gophers" fmt.Println(len(s)) fmt.Println(len([]rune(s))) } 運行結果: 19 11
通過對比我們可以發現中文字符每個占據3個字節,如果使用byte則需要三個不同的值,而使用rune剛好可以完整表達。
引出golang中關于字符串的說明
- Go 源代碼始終為 UTF-8。
- 字符串可以包含任意字節。
- 字符串文字中不包含字節級轉義符時字符串始終包含有效的 UTF-8 序列。
- 代表 Unicode 碼點的字節序列稱為?
rune
。 - 在 Go 中不會保證字符串中的字符被規范化。
值得注意的地方
在前面已經提到過,golang中沒有char這個概念,有的只是byte(uint8)單個字符的代表。因此要如何實現string呢?這個待會再講。我們現在主要介紹string遍歷過程中的問題。請看下面的例子
func main() { s := "我是一個gophers" for i, v := range s { fmt.Printf("第%d個值,類型為%T結果為:%v\n", i, v, string(v)) } for i, v := range s { fmt.Printf("第%d個值,類型為%T結果為:%v\n", i, v, string(s[i])) } } 運行結果: 第0個值,類型為int32結果為:我 第3個值,類型為int32結果為:是 第6個值,類型為int32結果為:一 第9個值,類型為int32結果為:個 第12個值,類型為int32結果為:g 第13個值,類型為int32結果為:o 第14個值,類型為int32結果為:p 第15個值,類型為int32結果為:h 第16個值,類型為int32結果為:e 第17個值,類型為int32結果為:r 第18個值,類型為int32結果為:s ------------------------------------------- 第0個值,類型為int32結果為:? 第3個值,類型為int32結果為:? 第6個值,類型為int32結果為:? 第9個值,類型為int32結果為:? 第12個值,類型為int32結果為:g 第13個值,類型為int32結果為:o 第14個值,類型為int32結果為:p 第15個值,類型為int32結果為:h 第16個值,類型為int32結果為:e 第17個值,類型為int32結果為:r 第18個值,類型為int32結果為:s
通過比對和循環我們可以得知,golang中對于string的循環,如果是中文則需要注意他的下標序號是以3
為差值,字符是以1
為差值.通過s[i]
和v
的比對可以知道為什么golang中需要選擇rune作為字符串的轉換值.如果轉化是一個中文的話,一個字節的byte是無法容納的,而rune解決了這個問題.
介紹string類型
關于string類型,在go標準庫builtin中有如下說明:
// string is the set of all strings of 8-bit bytes, conventionally but not // necessarily representing UTF-8-encoded text. A string may be empty, but // not nil. Values of string type are immutable. type string string
也就是說:string是8位字節的集合,通常但不一定代表UTF-8編碼的文本.string可以為空,但是不能為nil.string的值是不能改變的. 而在go語言的源碼中我們可以看到string的構成:
type stringStruct struct { str unsafe.Pointer len int }
stringStruct
就是string
的一個對象,這個str
就是一個指向字符數組首位的一個指針.len
就是這個字符串的長度.那么這個數組指的是什么呢?其實就是一個[]byte
,string內部就是通過這個字符切片組成的。而這個str就是指向了這個切片的首地址.因此也解釋了一個現象,為什么[]byte
中的值可以被修改,而string
中的值無法被修改.也正因如此copy內置函數才可以將string類型復制為[]byte類型.
字符串的值不能被更改,但可以被替換. string在底層都是結構體stringStruct{str: str_point, len: str_len},string結構體的str指針指向的是一個字符常量的地址,這個地址里面的內容是不可以被改變的,因為它是只讀的,但是這個指針可以指向不同的地址.
為什么替換字符時string比[]byte效率慢?
由于每次替換string
的值時,string
的str
指針無法進行改變指向,因此程序內部就需要去新開辟一個指針指向新的[]byte
,然后先前分配的string
內存就會被GC所回收.這是導致string相較于[]byte操作低效的根本原因.
思考string、byte、rune之間的關系
Go語言把字符分?byte
?和?rune
?兩種類型處理.byte
?是類型?unit8
?的別名,用于存放占 1 字節的 ASCII 字符,如英文字符,返回的是字符原始字節.rune
?是類型?int32
?的別名,用于存放多字節字符,如占 3 字節的中文字符,返回的是字符 Unicode 碼點值.
總結
- string無法進行修改,只能進行替換
- string底層由一個指針指向[]byte
- rune主要用來表示碼點并處理大于1字節小于4個字節的特殊字符
- 中文字符每個碼點占據多個字節,并且在string循環中通過rune表示
原文鏈接:https://juejin.cn/post/7174389358974205965
相關推薦
- 2022-12-10 Android入門之TextClock的使用教程_Android
- 2022-09-09 C++中vector<vector<int>?>的基本使用方法_C 語言
- 2021-12-14 RHCE橋接,免密登錄和修改端口號介紹_Linux
- 2022-04-23 Android自定義View實現數字雨效果的全過程_Android
- 2022-09-09 使用python怎樣產生10個不同的隨機數_python
- 2023-07-05 讓Linux中的SCP遠程復制不再需要輸入密碼
- 2023-01-10 利用C#實現修改圖片透明度功能_C#教程
- 2022-04-29 C#開發Winform控件之打開文件對話框OpenFileDialog類_C#教程
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支