Golang字符编码

在平常使用Go时,可能遇到的字符编码和转换等情况,因此有必要我们对其有一定的底层编码的了解,在此谈一谈Go编码中的strings, bytes, runes, characters。

strings

在Go中一个字符串实际是一个字节片,也就是一个字符串S在底层是通过bytes数组来存储的。 如果字符串中的某个字节不是有效的ASCll和有效的UTF-8,那么打印出来的外观随环境变化

下面有几个简单的例子(对比ASCll码表):

//(1)访问字符串的单个字节
 S := "AaBbCc"
 for _, v := range S {
   fmt.Println(v)
 }
//输出:65 97 66 98 67 99

characters

常由 8个二进制位(一个字节)来表示一个 characters 。例如:0100 0001表示A,其中0100称为高四位,0001称为低四位 。

//(1)打印字符
 S := "AaBbCc"
 for _, v := range S {
   fmt.Printf("%c",v)
 }

//输出:A a B b C c

bytes

是uint8的别名,在所有方面都等同于uint8。 它是用于区分字节值和8位无符号整数值 ,常用于处理ASCll字符

// byte is an alias for uint8 and is equivalent to uint8 in all ways. It is
// used, by convention, to distinguish byte values from 8-bit unsigned
// integer values.
type byte = uint8

runes

从源码的解释来看是int32的别名和代表一个UTF-8字符,所有方面都等同于int32。它是用于区分字符值和整数值。常用于处理Unicode或UTF-8字符 ,而Go的默认编码为UTF-8

// rune is an alias for int32 and is equivalent to int32 in all ways. It is
// used, by convention, to distinguish character values from integer values.
type rune = int32
//例(1)
Runes := []rune{'a','A','B'}
for _, v := range Runes  {
   fmt.Printf("%c Type : %s\n",v,reflect.TypeOf(v))
}
//输出:
a Type : int32
A Type : int32
B Type : int32
 
//例(2)
S := "你好,world" //一个汉字占3个字节算3个长度
fmt.Println("bytes =", len(S),	"runes =", utf8.RuneCountInString(S))
//输出:bytes = 12 runes = 8,因为len是计算字节长度,而在utf8的标准库下的RuneCountInString方法是计算字符长度

注:Go里面的默认编码为UTF-8

总结

在Go中字符串是由字节构建的,因此对它们进行索引将生成字节,而不是字符。如果你需要处理UTF-8,你可能要注意一下rune类型的使用,同时Go的标准库为解释UTF-8提供了一个Unicode/UTF-8 库。其实现了 实现了对UTF-8文本的常用函数和常数的支持,包括rune和utf-8编码byte序列之间互相翻译的函数,感兴趣的可以去了解一下。