猿问

string vs []byte 类型定义

如果我有此代码,它将按预期工作:


package main

import "strconv"


type text []byte


func main() {

   hello := text("hello")

   _ = strconv.AppendQuote(hello, " world")

}

但这段代码失败了:


package main

import "strconv"


type text string


func 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


繁星点点滴滴
浏览 131回答 3
3回答

喵喔喔

您需要将语言规范中的几个定义拼凑在一起,以了解发生了什么:首先是可分配性: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中的语言规范定义:预先声明的字符串类型是字符串;它是一个定义的类型。所以分配text给string不满足可分配性的条件,它会产生编译器错误。

开心每一天1111

您正在寻找的是在可分配性下:https://go.dev/ref/spec#Assignability尤其是:x 的类型 V 和 T 具有相同的基础类型,并且 V 或 T 中的至少一个不是定义的类型。在这两种情况下,基础类型都是相等的([]byte是必需的,text在情况 1 中传递,string是必需的,text在情况 2 中传递),但[]byte不是定义的类型string,所以它适用于第一种情况,但不适用于第二种情况.

子衿沉夜

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"),为了让它工作。
随时随地看视频慕课网APP

相关分类

Go
我要回答