string in golang
總結hello世界
字元
編號二進位制
h104
0110 1000
e101
0110 0101
l108
0110 1100
l108
0110 1100
o111
0110 0111
世19990
01001110 00010110
界30028
01110101 01001100
如果不加處理直接存放就是01101000|01100101|01101100|01101100|01100111|0100111000010110|0111010101001100
,可以發現如果將分隔符去掉我們完全不知道這些位元串將要表達什麼意思。
解決方案 編號
編碼模板
[0,127]
0???????
[128,2047]
110????? 10??????
[2048,65536]
1110???? 10?????? 10??????
比如對於世
編號19990
二進位制表示01001110 00010110
變長編碼 11100100
10111000
10010110
以上編碼方式就是所謂的utf-8
編碼,也就是go語言預設的編碼方式
var str string = "hello"
在c中字串變數存放著一塊以\0
結尾的連續記憶體的起始位址,在go中字串變數不光存放這個位址,還存放著這塊連續記憶體用多少個位元組(原始碼包src/runtime/string/string.go:stringstruct
)
type stringstruct struct
string的資料結構跟切片有些類似,只不過切片還有乙個表示容量的成員,事實上string和切片準確來說是byte
經常發生交換
var str string
str =
"hello 世界"
字串生成時,會先構建stringstruct物件,在轉換成string,原始碼:
func
gostringnocopy
(str *
byte
)string
s :=*(
*string
)(unsafe.
pointer
(&ss)
)return s
}
字串拼接
字串可以方便地拼接str := "str1" + "str2
即便有非常多的字串需要拼接,效能上也有比較好的保證,因為新字串的記憶體空間是一次分配完成的,所以效能消耗主要在拷貝資料上
在runtime
包中,使用concatstrings()函式來拼接字串。在乙個拼接語句中,所有待拼接的字串都被編譯器組織到乙個切片中傳入concatstrings函式,拼接的過程需要遍歷兩次切片 ,第一次獲取長度來申請記憶體,第二次將字元逐個拷貝過去(以下是偽**)
func
concatstrings
(a [
]string
)string
//分配記憶體 返回乙個string 和 slice 它們共享記憶體
s,b :=
rawstring
(length)
//string無法修改 可以通過切片修改
for_
,str :=
range a
return s
}
rawstring() 的原始碼,初始化乙個指定大小string同時返回乙個切片二者共享同一塊記憶體空間,後面向切片中拷貝資料,就間接地修改了string
func
rawstring
(size int
)(s string
, b [
]byte
)return
}
型別轉換
byte 轉 string
func
slicebytetostring
(buf *tmpbuf, b [
]byte
)(str string
)else
//構建字串
stringstructof
(&str)
.str = p
stringstructof
(&str)
.len
=len
(b)//將切片底層陣列拷貝到字串
memmove
(p,(*(
*slice)
(unsafe.
pointer
(&b)))
.array,
uintptr
(len
(b))
)return
}
string 轉 bytefunc
stringtoslicebyte
(buf *tmpbuf, s string)[
]byte
b = buf[
:len
(s)]
}else
copy
(b, s)
return b
}
golang的string不包含記憶體空間,只有乙個記憶體的指標,這樣的好處是string變得非常輕量,可以方便地進行傳遞而不用擔心記憶體拷貝 go專家程式設計系列(2)常見資料結構 slice
slice的實現原理 又稱動態陣列,依託陣列實現,可以方便地進行擴容和傳遞,實際使用時比陣列更靈活。type slice struct 以上是go中slice的宣告。簡單表示式 a low hihg 如果 a 為陣列或者切片,則該表示式將切取a low high 的元素,如果 a 為string 該...
go專家程式設計系列(3)常見資料結構 iota
我們知道iota常用於cost表示式中,其值是從0開始的,const宣告快中每增一行,iota值自增1 const a0,b0 1 iota,1 iota 1 a1,b1 a3,b3 注意iota識別符號只能用於常量表示式中,那麼想要了解iota是如何運作的,就要看看go的編譯器是如何處理常量宣告的...
常見資料結構
陣列 array 在程式設計中,為了處理方便,把具有相同型別的若干變數按有序的形式組織起來。這些按序排列的同類資料元素的集合稱為陣列。在c語言中,陣列屬於構造資料型別。乙個陣列可以分解為多個陣列元素,這些陣列元素可以是基本資料型別或是構造型別。因此按陣列元素的型別不同,陣列又可分為數值陣列 字元陣列...