bit和byte是什么?

bit

bit是位的意思,位是计算机中存储数据的最小单位,一个bit是一个0或1,中文叫做一个二进制位

byte

byte 是字节的意思,字节是计算机存储容量的基本单位,一个字节由8位二进制数组成
在计算机内部,一个字节可以表示一个数据,也可以表示一个英文字母,两个字节可以表示一个汉字。

bit 与 byte区别

容量大小不同

  • 1byte又称为一个字节,用一个字节(Byte)储存,可区别256个数字。 1 Byte = 8 bit
  • Bit 只能代表一个内容,(0或者1,其中的一个),1 Byte 代表 256 个内容 = 2 的 8 次方。

    存储数据类型不同

  • 一个byte由8 bits 所组成,可代表一个字元(A~Z)、数字(0~9)、或符号(,.?!%&+-*/),是记忆体储存资料的基本单位,至於每个中文字则须要两bytes。

  • bit是电脑记忆体中最小的单位,在二进位电脑系统中,每一bit 可以代表0 或 1 的数位讯号。

Go中的 rune和byte 以及字符串

image.png

  • byte和uint8等价;int32和rune等价
  • rune的目的是国际化,使非英文字符也能表示,比如中文就是占3个byte,但可以用1个rune来表示。
  • 实际应用中,字符串的迭代是按照rune的个数,也就是unicode编码方式去迭代的。
  • rune占内存会多一点,但是不会出现因为编码方式的导致的错误,实际开发中适合
  • rune可以取负值!
  • 字符中单引号表示,字符串用双引号表示

byte

占用1个节字,就 8 个比特位,所以它和 uint8 类型本质上没有区别,它表示的是 ACSII 表中的一个字符

如下这段代码,分别定义了 byte 类型和 uint8 类型的变量 a 和 b。

  1. func test() {
  2. var a byte = 65
  3. // 8进制写法: var c byte = '\101' 其中 \ 是固定前缀
  4. // 16进制写法: var c byte = '\x41' 其中 \x 是固定前缀
  5. var b uint8 = 66
  6. fmt.Printf("a 的值: %c , b 的值: %c \n", a, b) // a 的值: A , b 的值: B
  7. // 或者使用 string 函数
  8. fmt.Println("a 的值:", string(a), ", b 的值:", string(b)) // a 的值: A , b 的值: B
  9. //在 ASCII 表中,由于字母 A 的ASCII 的编号为 65 ,字母 B 的ASCII 编号为 66,
  10. // 所以上面的代码也可以写成这样
  11. var A byte = 'A'
  12. var B uint8 = 'B'
  13. fmt.Printf("A 的值: %c , B 的值: %c", A, B) // A 的值: A , B 的值: B
  14. }

byte和uint8等价,无符号位,取值范围在0-255。

  1. var num1 byte = 0
  2. var num2 byte = 255
  3. var num3 byte = 256 // '256' (类型 untyped int) 不能由类型 byte 表示 超出范围

小写字符a,对应ascII码是97,则二进制为0110 0001。97在0-255之间。

rune

占用4个字节,共32位比特位,所以它和 uint32 本质上也没有区别。
它表示的是一个 Unicode字符(Unicode是一个可以表示世界范围内的绝大部分字符的编码规范)。

  1. func test2() {
  2. var a byte = 'A'
  3. var b rune = 'B'
  4. fmt.Printf("a 占用 %d 个字节, b 占用 %d 个字节", unsafe.Sizeof(a), unsafe.Sizeof(b))
  5. // a 占用 1 个字节, b 占用 4 个字节
  6. }

由于 byte 类型能表示的值是有限,只有 2^8=256 个。
所以如果你想表示中文的话,你只能使用 rune 类型。

  1. var name rune = '中'

或许你已经发现,上面我们在定义字符时,不管是 byte 还是 rune ,我都是使用单引号,而没使用双引号。

  1. var a byte = 'A'
  2. var b rune = 'A'
  3. var c rune = '中'
  4. fmt.Println(a) // 65
  5. fmt.Println(b) // 65
  6. fmt.Println(c) // 20013

string

上面说的byte 和 rune 都是字符类型,若多个字符放在一起,就组成了字符串,也就是这里要说的 string 类型。
string 本质就是一个byte数组。
比如 hello ,对照 ascii 编码表,每个字母对应的编号是:104,101,108,108,111

  1. var str1 string = "hello"
  2. var str2 []byte = []byte{104, 101, 108, 108, 111}
  3. fmt.Println(str1) // hello
  4. fmt.Printf("%s\n", str2) // hello
  5. fmt.Println(str2) // [104 101 108 108 111]

通过以上学习,我们知道字符分为 byte 和 rune,占用的大小不同。

Go 语言的 string 是用 uft-8 进行编码的。
英文字母占用一个字节,而中文字母占用 3个字节

  1. func test4() {
  2. var str1 string = "hello"
  3. var str2 string = "你好"
  4. // golang的字符串都是以UTF-8格式保存,每个中文占用3个字节
  5. // 因此使用 len() 获得两个中文文字对应的 6 个字节
  6. fmt.Println(len(str1)) // 5
  7. fmt.Println(len(str2)) // 6
  8. // 字符个数
  9. fmt.Println(utf8.RuneCountInString(str1)) // 5
  10. fmt.Println(utf8.RuneCountInString(str2)) // 2
  11. }

转换

字符转byte 和 rune

  1. byte 和 rune 之间可以转换,byte 转向 rune 时不会出错
  2. rune 转向 byte 时会出现问题
    如果 rune 表示的字符只占用一个字符,不超过 uint8 时不会出错;超过时直接转换编译无法通过,可以通过引用转换,但是会舍去超出的位,出现错误结果。 ```go func test5() { char := ‘你’

    v1 := rune(char) v2 := byte(char)

    s1 := strconv.FormatInt(int64(v1), 2) s2 := strconv.FormatInt(int64(v2), 2)

    fmt.Printf(“v1: %c, type: %T, %v”, v1, v1, s1) // v1: 你, type: int32, 100111101100000 fmt.Println()

    // 超出 fmt.Printf(“v2: %c, type: %T, %v”, v2, v2, s2) // v2: `, type: uint8, 1100000

    /* v1: 你, type: int32, 100111101100000 v2: `, type: uint8, 1100000 / }

  1. <a name="QczgL"></a>
  2. ### 字符串转byte 和 rune
  3. ```go
  4. func test6() {
  5. str := "你好"
  6. b := []byte(str)
  7. c := []rune(str)
  8. fmt.Printf("b: %v b: %c type: %T \n", b, b, b) // b: [228 189 160 229 165 189] b: [ä ½ å ¥ ½] type: []uint8
  9. fmt.Printf("c: %v c: %c type: %T \n", c, c, c) // c: [20320 22909] c: [你 好] type: []int32
  10. }
  11. // 可以看出 byte 并不能正确解析超过 1 byte 的字符,需要使用 rune
  12. b: [228 189 160 229 165 189] b: [ä ½ å ¥ ½] type: []uint8
  13. c: [20320 22909] c: [你 好] type: []int32//rune占用4个字节
  1. func test7() {
  2. str := "abcdef"
  3. //string 转[]byte
  4. b := []byte(str)
  5. fmt.Printf("b: %c \n", b) // b: [a b c d e f]
  6. //[]byte转string
  7. str = string(b)
  8. fmt.Printf("str: %s \n", str) // str: abcdef
  9. //string 转 rune
  10. r := []rune(str)
  11. fmt.Printf("r: %c\n", r) //r: [a b c d e f]
  12. //rune 转 string
  13. str = string(r)
  14. fmt.Printf("str: %s \n", str) // str: abcdef
  15. }

扩展资料

计算机存储单位一般用bit、B、KB、MB、GB、TB、PB、EB、ZB、YB、BB、NB、DB……来表示,它们之间的关系是:
位 bit (比特)(Binary Digits):存放一位二进制数,即 0 或 1,最小的存储单位。[英文缩写:b(固定小写)]

字节byte:8个二进制位为一个字节(B),最常用的单位。

1 Byte(B) = 8 bit
1 Kilo Byte(KB) = 1024B
1 Mega Byte(MB) = 1024 KB
1 Giga Byte (GB)= 1024 MB
1 Tera Byte(TB)= 1024 GB
1 Peta Byte(PB) = 1024 TB
1 Exa Byte(EB) = 1024 PB
1 Zetta Byte(ZB) = 1024 EB
1Yotta Byte(YB)= 1024 ZB
1 Bronto Byte(BB) = 1024 YB
1Nona Byte(NB)=1024 BB
1 Dogga Byte(DB)=1024 NB
1 Corydon Byte(CB)=1024DB
1 Xero Byte (XB)=1024CB

参考: