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

string vs []byte 类型定义

string vs []byte 类型定义

Go
繁星点点滴滴 2022-10-24 15:43:34
如果我有此代码,它将按预期工作:package mainimport "strconv"type text []bytefunc main() {   hello := text("hello")   _ = strconv.AppendQuote(hello, " world")}但这段代码失败了:package mainimport "strconv"type text stringfunc main() {   hello := text("hello")   // cannot use hello (type text) as type string in argument to strconv.Quote   _ = strconv.Quote(hello)}为什么一个通过,另一个失败?我检查了文档 [1],但没有看到任何解释差异的内容。https://go.dev/ref/spec#Type_definitions
查看完整描述

3 回答

?
喵喔喔

TA贡献1735条经验 获得超5个赞

您需要将语言规范中的几个定义拼凑在一起,以了解发生了什么:

首先是可分配性:

x 的类型 V 和 T 具有相同的基础类型,并且 V 或 T 中的至少一个不是定义的类型。

然后你需要检查你的 V 和 T。

在您的第一个代码片段中,您有type text []byte(V)和一个AppendQuote所需参数是[]byte(T)的函数。

V 和 T 是否具有相同的基础类型?是的。text的基础类型[]byte由您定义,并且[]byte是复合类型,其基础类型是它本身。从类型

每个类型 T 都有一个基础类型:如果 T 是预先声明的布尔、数字或字符串类型之一,或者是类型文字,则相应的基础类型是 T 本身

以及上面的段落:

复合类型——[...] slice,[...]——可以使用类型文字来构造。

而且,V 或 T 中的至少一个不是定义的类型吗?是的,[]byte如上所述是复合类型。

因此,类型的变量text可分配给[]byte,包括将参数传递给函数。


在您的第二个代码片段中,您有type text string(V)和一个Quote所需参数是string(T)的函数。

V 和 T 是否具有相同的基础类型?是的。一个根据定义,另一个是预先声明的类型string(与上面的引用相同)。

最后,是否至少有一个 V 或 T不是定义的类型?不!两者都是定义类型。text由您定义,并由字符串类型string中的语言规范定义:

预先声明的字符串类型是字符串;它是一个定义的类型。

所以分配textstring不满足可分配性的条件,它会产生编译器错误。


查看完整回答
反对 回复 2022-10-24
?
开心每一天1111

TA贡献1836条经验 获得超13个赞

您正在寻找的是在可分配性下:

https://go.dev/ref/spec#Assignability

尤其是:

x 的类型 V 和 T 具有相同的基础类型,并且 V 或 T 中的至少一个不是定义的类型。

在这两种情况下,基础类型都是相等的([]byte是必需的,text在情况 1 中传递,string是必需的,text在情况 2 中传递),但[]byte不是定义的类型string,所以它适用于第一种情况,但不适用于第二种情况.


查看完整回答
反对 回复 2022-10-24
?
子衿沉夜

TA贡献1828条经验 获得超3个赞

AppendQuote接受[]byte作为参数,并且您hello被定义为text类型,这是[]byte您的类型定义中的一个,这就是它起作用的原因。

func strconv.AppendQuote(dst []byte, s string) []byte 见源代码

而 Quote 接受字符串作为参数,

func strconv.Quote(s string) string 见源代码

你的 hello 类型是[]byte,而不是字符串。这就是为什么它不起作用。您要么必须使用第一种情况,要么将您的 hello 更改为字符串。例如_ = strconv.Quote("hello"),为了让它工作。


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

添加回答

举报

0/150
提交
取消
微信客服

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

帮助反馈 APP下载

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

公众号

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