Go语言中的字符和字符串

Go语言中的字符

在Go语言中,没有字符类型,字符类型是rune类型,rune是int32的别称。

下面用一个简单的程序来演示字符类型:

package main

import (
    "fmt"
    "reflect"
)

func main() {
    r := '我'
    fmt.Printf("%q的类型为:%t 二进制为:%b\n", r, r, r)

    rType := reflect.TypeOf(r).Kind()
    fmt.Printf("r的实际类型为:%s\n", rType)
}

程序输出:

'我'的类型为:%!t(int32=25105) 二进制为:110001000010001
r的实际类型为:int32

Go语言天生支持Unicode,那我产生一个问题:Unicode字符的长度是多少?
这个问题的问法有没有问题?其实仔细想想,这样问是有问题的。首先,Unicode的基础是一个有编号的字符集,在字符集之上又规定了模块化的编码等等技术层次,各种具体的编码形式并不一致。因此,严格来说,Unicode是没有“长度”这一说的,它是抽象的字符,只有Unicode的编码才有具体的字节长度。而且不同的编码实现,长度也不一样。

Unicode 目前规划的总空间是17个平面(平面0至16),每个平面有 65536 个码点。我们常用的平面0(「Basic Multilingual Plane」,即「BMP」)码点范围为0x0000 至 0xFFFF,这并不是 Unicode 的全部。

BMP 的字符是 Unicode 中最基础和最常用的一部分,以 UTF-16 编码时使用2字节,以 UTF-8编码时使用1至3字节。超出 BMP 的字符以 UTF-16 或 UTF-8 编码都需要4字节。另外还有一个比较少用的编码形式,UTF-32,它编码任何 Unicode 字符都需要4个字节。

Go语言中的字符串

Go语言的字符串有两种方式来表示:

  • 双引号,可以使用转义字符,如s := "Go语言字符串\n不能跨行赋值"
  • 反引号,字符串跟反引号中的格式一样,即Raw Type
s := `Go原格式字符串
    可以跨行`

Go语言的字符串是以UTF-8格式编码并存储的,下面有一个简单的例子:

package main

import (
    "fmt"
)

func main() {
    s := "我"
    fmt.Printf("s的类型为:%t, 长度为:%d, 16进制为:%x\n", s, len(s), s)

    for i, b := range []byte(s) {
        fmt.Printf("第%d个字节为:%b\n", i, b)
    }
}

程序输出:

s的类型为:%!t(string=我), 长度为:3, 16进制为:e68891
第0个字节为:11100110
第1个字节为:10001000
第2个字节为:10010001

变量s中存放的是这个字符串的UTF-8编码,当你使用len(s)函数获取字符串的长度时,获取的是该字符串的UTF-8编码长度,存储一个字符可能需要 2个、3个或者4个字节,它是不固定的。

UTF-8的编码遵循如下2条规则:

  • 对于单字节的符号,字节的第一位设为0,后面7位为这个符号的unicode码。因此对于英语字母,UTF-8编码和ASCII码是相同的。
  • 对于n字节的符号(n>1),第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的unicode码。

根据这两条简单的规则,我们可以把UTF-8编码转换为Unicode的码点:

//utf8转为unicode
          1110 0110 1000 1000 1001 0001 // s
               0110   00 1000   01 0001 // s utf8 -> unicode
          0000 0000 0110 0010 0001 0001 // s utf8 -> unicode
0000 0000 0000 0000 0110 0010 0001 0001 // r

我们可以看到上面推导的结果跟程序的输出结果相符。

参考

转载于:https://www.cnblogs.com/gowk/p/char-and-string-in-go.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值