20210209关于[]byte和[]rune(2) - ziyouzy/2021blog GitHub Wiki

回到正题,这里的主题其实探讨的是某种编码(如ascii,utf8)的“储存方式”,而不是二进制数的“显示方式”
刚才的内容是显示方式的范畴
而对于储存方式,其实是面向2进制数的,也就是你在某个输入框,无论用哪种方式,无论借助哪种输入方式,印在这里的一串2进制数

而编译器把某个字符塞进内存(或者说其自身缓存,非储存)的方式不会借助任何数据类型: 1,2,4这些是整型,1.2浮点型,0x71整型(16进制),'A'byte,'赵'等,他们的底层都是二进制数
但是如果要进行对这些“东西”进行操作,就需要借助某种内置(非内置)数据类型了,如将1(二进制数00000001)赋值给int8 i这样的变量
这些各种各样的操作里,也会包括存储这件事,其实先用正确的方式存储才是一切其他操作的基础,如字符串拼接,遍历,更新等

[]byte{"我的天啊"}这句会进行下面这些事:
第一步将"我的天啊"所对应的2进制数们储存为string这个数据类型,
这第一步又是以将"我的天啊"先储存为一个byte类型的数组为真正的第一步的因为string的底层是byte数组而非rune数组

s := string("我的天")和ss := string("OMG")的区别在于:
使用的2进制总数不一样,从而使用的字节(8为2进制)总数也不一样,这一步是不会存在所谓的"溢出"问题的
但是如果进行len(string("我的天"))和len(string("OMG"))则前者的值不会是3,因为len的值为底层字节数组的len,这个len的计算方式会是纯粹的2进制数总个数/8
在此如果进行如下遍历方式则会出错:

for i:=0;i<len(s);i++{
    fmt.Println(s[i])
}

则会出现所谓的“溢出”问题,或者说显示的“乱码问题”
而如果操作方式是:

for han := range s{
    fmt.Println(han)
}

则就可以避免出现这问题,因为range会隐式进行unicode解码操作(utf8.RuneCountInString(s)也是unicode解码相关的一个方法,只不过程序员会对他进行显示调用) 注意隐式进行unicode解码是string这个数据类型的特性,如果你直接进行[]byte{"我的天"}的for range操作则是行不通的

但是[]rune则可以,因为他是int32而不是int8,这就足够来容纳任何一个ut8字符了,如论是for{}还是for range都可以胜任

于是可以看出我现在代码所存在的问题

p.config.signalChan<-append([]byte("仅仅作为示范(AnotherExmaple1)"),[]byte("mode类型与Exmaple类型不匹配,可理解为Run()失败")

其实并不是太大的问题:
因为无论golang会直接将"仅仅作为示范(AnotherExmaple1)"转化为[]byte
还是先转化为string在转化为[]byte,其都不会造成数据的丢失(2进制数的丢失,len(所有的二进制数)是不会变(丢)的len(所有的byte)也是不会变(丢)的) 而p.config.signalChan也是个[]byte类型的管道,所以这些其实都没问题
真正用的时候,最省事的方法是强制转换为string在进行for range的操作
而强制转化为rune也是可以的,只不过string能解决的问题也没必要用rune罢了