为了账号安全,请及时绑定邮箱和手机立即绑定

符文和字节(切片)之间的转换

符文和字节(切片)之间的转换

Go
蝴蝶不菲 2022-06-21 15:53:23
Go 允许从runeto转换byte。rune但是对于is的底层类型int32(因为 Go 使用 UTF-8),对于byteis uint8,转换因此会导致信息丢失。但是,无法从符文转换为[]byte.var b byte = '©'bs := []byte(string('©'))fmt.Println(b)fmt.Println(bs)// Output169[194 169]为什么 Go 允许转换 from runetobyte而不是runeto []byte?
查看完整描述

3 回答

?
精慕HU

TA贡献1845条经验 获得超8个赞

Go 支持从runeto的转换,byte就像它对所有数字类型对所做的那样。如果不允许转换,那将是一个令人惊讶的特殊int32情况byte

但底层的类型runeint32(因为 Go 使用 UTF-8)

这遗漏了一个重要的细节:runeint32. 它们是同一类型。

确实,底层类型是runeis int32,但这是因为runeandint32是相同的类型,而内置类型的底层类型是类型本身。

Unicode 代码点作为int32值的表示与 UTF-8 编码无关。

因此,转换会导致信息丢失

是的,数字类型之间的转换可能会导致信息丢失。这是 Go 中的转换必须是显式的原因之一。

请注意,该语句var b byte = '©'不进行任何转换。该表达式'@'是一个无类型的常量。

如果分配无类型常量导致信息丢失,编译器会报告错误。例如,该语句var b byte = '世'会导致编译错误。

该语言中的所有 UTF-8 编码功能都与string类型有关。UTF-8 感知转换都是与string类型之间的。可以支持转换,[]byte(numericType)但这会将 UTF-8 编码带到string类型之外。

Go 作者对包含string(numericType)转换感到遗憾,因为它在实践中不是很有用,而且转换也不是某些人所期望的。库函数是该功能的更好位置。


查看完整回答
反对 回复 2022-06-21
?
撒科打诨

TA贡献1934条经验 获得超2个赞

是的,可以从 rune 转换为 []byte(例如通过字节)并再次转换回来。


package main


import "fmt"


func main() {

    var b byte = '©'

    bs := []byte{b}

    fmt.Printf("%T %v\n", b, b)   // uint8 169

    fmt.Printf("%T %v\n", bs, bs) // []uint8 [169]


    s := string(bs[0]) // s := string(b) works too.

    r2 := rune(s[0]) // r2 := rune(b) works too.

    fmt.Printf("%T %v\n", s, s) // string ©

    fmt.Printf("%T %v\n", r2, r2) // int32 169

}


查看完整回答
反对 回复 2022-06-21
?
摇曳的蔷薇

TA贡献1793条经验 获得超6个赞

这种行为的原因与合法的原因相同


var b int32

b = 1000000

fmt.Printf("%b\n", b)

fmt.Printf("%b", uint8(b))


// Output:

// 11110100001001000000

// 1000000

当您将具有较大内存占用的类型的数据放入具有较小内存占用的类型时,您应该期望转换为松散数据。


此外,对于 a 编码,rune您可以使用EncodeRune,它确实使用 a []byte。


查看完整回答
反对 回复 2022-06-21
  • 3 回答
  • 0 关注
  • 173 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号