[TOC]
1.类型定义
strings类型在go语言中是一个bytes的切片,可以使用双引号来构建strings.strings在golang中使用的是utf-8编码。使用byte类型切片的主要原因与ASCII码与unicode共存的原因类似,由于英文只使用一个字节就可以全部表示,但是其他字符表示可能需要多个字节,所以为了节省存储空间,默认采用byte。
注意strings是一个只读类型的byte切片,所以是不可更改类型。strings实际保存的是二进制byte而不是unicode码,或者其他的编码形式。下面是一个字符串的字面量(string literal) ,可以使用2位十六进制表示一个特定的byte
Copy const sample = "\xbd\xb2\x3d\xbc\x20\xe2\x8c\x98"
由于strings是一个byte类型的切片,所以可以使用
可以使用一个byte的切片进行显式的定义string
2. 访问string 的每一个字符
因为strings是一个byte的切片,所以可以访问其中的每一个字符
Copy func printBytes (s string ) {
for i := 0 ; i < len (s); i ++ {
fmt. Printf ( " %x " , s[i])
}
}
func printChars (s string ) {
for i := 0 ; i < len (s); i ++ {
fmt. Printf ( " %c " ,s[i])
}
}
func main () {
name := "Hello World"
printBytes (name)
printChars (name)
}
// 输出其十六进制编码
48 65 6c 6c 6f 20 57 6f 72 6c 64
H e l l o W o r l d
对于格式化输出,使用%x
输出十六进制编码,使用%c
输出相应字符。注意对于英文使用的是ASCII编码方式,所以对于每一个byte直接按位输出就是其正确编码;但是对于unicode编码,使用的是utf-8格式,所以需要使用三个字节表示一个字符,对于中文而言,每一字符占用三个字节.
Copy func printBytes (s string ) {
for i := 0 ; i < len (s); i ++ {
fmt. Printf ( " %x " , s[i])
}
}
func printChars (s string ) {
for i := 0 ; i < len (s); i ++ {
fmt. Printf ( " %c " , s[i])
}
for i, v := range s {
fmt. Printf ( " %#U : %c , %d \n" , v, v, i)
}
}
func main () {
name := "什么"
printBytes (name)
fmt. Printf ( "\n" )
printChars (name)
}
/*
e4 bb 80 e4 b9 88
ä » ä ¹
U+4EC0 '什': 什, 0
U+4E48 '么': 么, 3
*/
使用%#U
输出字符的unicode编码,每个字符使用三个字节的编码。
3.rune
对于unicode编码,如果使用bytes编码会出现错误,可以使用rune,一个32位整数表示。
Copy func printChars (s string ) {
runes := [] rune (s) // 建立rune切片
for i := 0 ; i < len (runes); i ++ {
fmt. Printf ( " %c " , runes[i])
}
}
// 正常输出
由于string是不可更改类型,如果需要对其进行更改,可以使用rune的切片进行处理
Copy func mutate (s [] rune , a rune ) {
s[ 0 ] = a
return string (s)
}
str = mutate ([] rune (str), 'a' )
4.utf-8 string的长度
对于string类型的长度不可以直接使用len()
函数进行计算,因为其包含unicode码,需要使用unicode/utf8
模块的utf8.RuneCountInString()
函数计算string的长度
Copy func leng_test (str string ) {
fmt. Println ( "The string:" , str)
fmt. Println ( "Use len():" , len (str))
fmt. Println ( "Acctually length:" , utf8. RuneCountInString (str))
}
// 对于中文,每一个字符使用三个字节表示,所以len 会是长度的3倍
5. 使用fmt.printf()
输出[]rune
对于一个字符串的字面量(string literal),可以使用十六进制表示特定的byte值,从而表示一个字符串,进行输出时可以使用多种格式化输出例如:
%x
输出十六进制代码, 可以在中间加空格,表示分隔
可以使用``表示一个raw string,字面string,里面只可以包含文字字符,而不可以包含其他字符。
Copy func main () {
const placeOfInterest = `⌘`
fmt. Printf ( "plain string: " )
fmt. Printf ( " %s " , placeOfInterest)
fmt. Printf ( "\n" )
fmt. Printf ( "quoted string: " )
fmt. Printf ( " %+q " , placeOfInterest)
fmt. Printf ( "\n" )
fmt. Printf ( "hex bytes: " )
for i := 0 ; i < len (placeOfInterest); i ++ {
fmt. Printf ( " %x " , placeOfInterest[i])
}
fmt. Printf ( "\n" )
}
//
plain string : ⌘
quoted string : "\u2318"
hex bytes: e2 8c 98