• wade
    2018-11-07
    而后三个十六进制数7231、597d和8005都相对较大,它们分别表示中文字符'爱'、'好'和'者'。这些中文字符对应的 UTF-8 编码值,都需要使用三个字节来表达。所以,这三个数就是把对应的三个字节来表达。所以,这三个数就是把对应的三个字节的编码值,转换为整数后得到的结果。

    "爱好者"对应的7231、597d、8005,不是UTF-8编码值,是unicode码点。unicode码点和最终计算器存储用的utf-8编码值不是一样的。转换成rune的时候rune切片每个元素存储一个unicode码点,也就是string里的一个字符转成rune切片的一个元素。string是以utf-8编码存储,byte切片也就是存储用的string用utf-8编码存储后的字节序。

    unicode和utf-8的关系,可以看这个文章
    http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html
    展开
    
     17
  • 冰激凌的眼泪
    2018-11-05
    src文件编码是utf8
    string是utf8编码的mb,len(string)是字节的长度
    string可以转化为[]rune,unicode码,32bit的数字,当字符看,len([]rune)为字符长度
    string可以转化为[]byte,utf8编码字节串,len([]byte)和len(string)是一样的
    for range的时候,迭代出首字节下标和rune,首字符下标可能跳跃(视上一个字符编码长度定)
    
     9
  • 冰激凌的眼泪
    2018-11-02
    看rune大小
    转成byte看长度
    加个小尾巴,range看间隔
    
     3
  • 韡WEI
    2018-11-15
    rune怎么翻译?有道查的:神秘的记号。为什么这么命名这个类型?有没有什么故事?
     1
     2
  • Gryllus
    2018-11-02
    终于追上了进度

    作者回复: 🐂

    
     2
  • 安排
    2019-09-18
    一个unicode字符在内存中存的是码点的值还是utf8对应的编码值?

    作者回复: 内存里存的是 UTF-8 的编码值,会由 1~4 个字节组成。Unicode 代码点是 Unicode 标准中用来唯一标识字符的东西。

     1
     1
  • qiushye
    2019-09-05
    str := "Go 爱好者 "fmt.Printf("Th...

    您在文章里举的这个例子在Go后面多加了空格,会让人误解成遍历字符串可以跳过空格,github代码里没问题。

    作者回复: 收到,谢谢。已经通知编辑修正了。

     1
     1
  • 🤔
    2019-04-22
    + isrunesingle.go

    ```go
    package show_rune_length

    func isSingleCharA(c rune) bool {
        return int32(c) < 128
    }

    func isSingleCharB(c rune) bool {
        data := []byte(string(c))
        return len(data) == 1
    }

    func isSingleCharC(c rune) bool {
        data := string(c) + " "

        for i, _ := range data {
            if i == 0 {
                continue
            }

            if i == 1 {
                return true
            } else {
                return false
            }
        }

        return false
    }
    ```

    + isrunesingle_test.go

    ```go
    package show_rune_length

    import (
        "testing"

        "github.com/stretchr/testify/assert"
    )

    type CharJudger func(c rune) bool

    func TestIsSingleChar(t *testing.T) {

        for _, judger := range []CharJudger{
            isSingleCharA,
            isSingleCharB,
            isSingleCharC,
        } {
            assert.True(t, judger('A'))
            assert.True(t, judger(rune(' ')))
            assert.False(t, judger('😔'))
            assert.False(t, judger('爱'))
        }
    }
    ```
    展开

    作者回复: 可以用 unicode/utf8 代码包中的 RuneCount 函数。

    
     1
  • Andylee
    2018-12-16
    这篇文章把unicode和utf8区分的不是很清楚,正如上面有个网友说的rune切变16进制输出是字符的unicode的码点,而byte切片输出的才是utf8的编码

    作者回复: 这么说没错,不过rune在底层也是字节串。

     1
     1
  • 思维
    2020-01-17
    这篇文章 收获很大
    
    
  • 疯琴
    2020-01-05
    Unicode、UTF来回来去看了好多文章,开始糊涂,多看逐渐就明白了,老师讲得挺清楚的。
    
    
  • 杨锦
    2020-01-04
    郝老师,请教一个问题,对于一个6字节的utf8编码,怎么判断是要解码成6个宽度为1字节宽度的的还是2个3字节宽度的呢?

    作者回复: 首先不存在6个字节的utf8编码的字符,只有1~4个字节的。其次,unicode/utf8把里有相应的API。要看原理,看它的源码就好了。

    
    
  • 虢國技醬
    2019-12-08
    二刷
    
    
  • 文武木子
    2019-10-10
    十六进制四个数字不是一共占用32位吗,一个字节不是8位嘛,这样不是占用4个字节吗?求大神解答

    作者回复: 你想问什么?十六进制的一位相当于二进制的四位。

     1
    
  • 党
    2019-07-30
    一个unicode字符点都是由两个字节存储,为什么在go语言中 type rune = int32 四个字节 而不是 type rune=16 两个字节啊

    作者回复: Unicode 代码点是一个抽象的概念,并且没有规定占用的字节数,只是说以“U+XXXX”的形式来表示。“X”还可能有 5 个或 6 个。

    Unicode 代码点是 Unicode 编码标准的一部分。但你要分清楚编码标准和编码格式(像 UTF-8、UTF-16 等等)的区别。前者是概念和表示法,后者是真正的落地格式。编码格式才是真正与存储占用(比如一个字符占用多少个字节)有关的东西。

    rune 类型的宽度是 4 个字节,那是因为 Go 语言使用 UTF-8 编码格式。这种格式编出来的码最多占用 4 个字节。

    
    
  • 张岳文
    2019-07-23
    我认为string的底层是Unicode, 而非UTF-8。只是string转成[]byte时,string转成了utf-8的序列。。。内存中的应该统一用unicode处理,而UTF-8是为了存储和传输才进行字节转换的。

    作者回复: 内存上的也是二进制储存的啊,Unicode 只是一个字符编码标准,不是编码格式。

    
    
  • benying
    2019-06-13
    打卡,讲的挺清楚的,谢谢
    
    
  • jacke
    2019-05-12
    string 底层是[]byte数组,我的疑问是:例子里面看出来,string转化为tune的时候,tune里面保存的是utf-8的代码点数据,string转化为[]byte的时候保存的是utf-8代码点对应的字节序。
    上面这些转化逻辑在哪里实现的?fmt.print里面?看了fmt.print找不到,string转为[]byte的实现函数stringtoslicebyte也没看到这部分逻辑

    作者回复: 你要知道,string 类型的值本身就是由 UTF-8 编码的一个个字节组成的,同时也可以看做是由一个个 Unicode 字符组成的。这不是在转换的时候才去做的。

    你既然已经找到了 stringtoslicebyte 函数,那就应该再去看看那个源码文件中的其他代码。可以从 rawstring 函数看起。等都看完了你就应该明白了。

    
    
  • Geek_1ed70f
    2019-03-14
    您是说 一个汉字的rune值 在计算机底层会被转成utf-8编码来 给计算机读取是吗?

    比如 一个"严"字 unicode为20005(十进制), utf-8编码是11100100 10111000 10100101(二进制),十进制就是14989477 , 我们平时打印只能看到 20005 它是什么时候转成14989477的啊

    作者回复: 存储的时候会以二进制的形式。另外如果你要看Unicode代码点。你这么转换比较混乱。你可以参看fmt包的文档,看看怎样才能把对应的进制值打印出来。

    
    
  • melody_future
    2019-03-06
    有点小晕,想请问下 rune 类型在内存的表现形式是 unicde 编码值,还是utf-8 编码值,你所说的底层指的是?

    作者回复: rune的底层表达使用的是Unicode代码点。
    但是,底层的存储用UTF-8编码。

    表达和存储这两者的关系你能分清楚吧?

    
    
我们在线,来聊聊吧