英文:
string vs []byte type definition
问题
如果我有这段代码,它会按预期工作:
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")
// 无法将hello(类型为text)作为strconv.Quote函数的参数类型string使用
_ = strconv.Quote(hello)
}
为什么一个通过了而另一个失败了?我查看了文档[1],但没有找到解释这个差异的内容。
英文:
If I have this code, it works as expected:
package main
import "strconv"
type text []byte
func main() {
hello := text("hello")
_ = strconv.AppendQuote(hello, " world")
}
but this code fails:
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)
}
Why does one pass and the other fail? I checked the docs [1], but I didnt see
anything that explained the difference.
- <https://go.dev/ref/spec#Type_definitions>
答案1
得分: 3
你要找的内容在"Assignability"下面:
https://go.dev/ref/spec#Assignability
具体来说:
x的类型V和T具有相同的底层类型,并且V或T中至少有一个不是定义类型。
在这两种情况下,底层类型是相等的(在情况1中需要[]byte
,并且传入的是text
,在情况2中需要string
,并且传入的是text
),但是[]byte
不是一个定义类型,而string
是,所以它适用于第一种情况,但不适用于第二种情况。
英文:
What you are looking for is under Assignability:
https://go.dev/ref/spec#Assignability
In particular:
> x's type V and T have identical underlying types and at least one of V or T is not a defined type.
In both cases, the underlying types are equal ([]byte
is required and text
is passed in case 1, string
is required and text
is passed in case 2), but []byte
is not a defined type and string
is, so it works for the first case, but not the second.
答案2
得分: 3
你需要从语言规范中整合几个定义来理解发生了什么:
首先是可赋值性:
x的类型V和T具有相同的基础类型,并且V或T中至少有一个不是定义类型。
然后你需要检查V和T。
在你的第一个代码片段中,你有type text []byte
(V),以及一个需要[]byte
(T)作为参数的函数AppendQuote
。
V和T具有相同的基础类型吗?是的。根据你的定义,text
的基础类型是[]byte
,而[]byte
是一个复合类型,其基础类型是它自身。根据类型:
每个类型T都有一个基础类型:如果T是预声明的布尔、数值或字符串类型,或者是一个类型字面量,则相应的基础类型是T本身。
以及上面的段落:
复合类型——[...] 切片,[...]——可以使用类型字面量构造。
而且,V或T中至少有一个不是定义类型吗?是的,如上所述,[]byte
是一个复合类型。
因此,text
类型的变量可以赋值给[]byte
,包括将参数传递给函数。
在你的第二个代码片段中,你有type text string
(V),以及一个需要string
(T)作为参数的函数Quote
。
V和T具有相同的基础类型吗?是的。一个是根据定义,另一个是预声明类型string
(与上述引用相同)。
最后,V或T中至少有一个不是定义类型吗?**不!**两者都是定义类型。text
是你定义的,而string
是语言规范中定义的字符串类型:
预声明的字符串类型是string;它是一个定义类型。
因此,将text
赋值给string
不满足可赋值性的条件,会导致编译器错误。
英文:
You need to piece together several definitions from the language specifications to understand what's going on:
First is Assignability:
> x's type V and T have identical underlying types and at least one of V or T is not a defined type.
Then you need to examine your V and T.
In your first code snippet you have type text []byte
(the V) and a function AppendQuote
whose required argument is []byte
(the T).
Do V and T have identical underlying types? Yes. text
's underlying type is []byte
by your definition, and []byte
is a composite type, whose underlying type is itself. From Types:
> Each type T has an underlying type: If T is one of the predeclared boolean, numeric, or string types, or a type literal, the corresponding underlying type is T itself
and the paragraph just above that:
> Composite types —[...] slice, [...] — may be constructed using type literals.
And, is at least one of V or T not a defined type? Yes, []byte
as stated above is a composite type.
Hence a variable of type text
is assignable to []byte
, including passing arguments to a function.
<hr>
In your second code snippet you have type text string
(the V) and a function Quote
whose required argument is string
(the T).
Do V and T have identical underlying types? Yes. One by definition, and the other one is the predeclared type string
(same quote as above).
Finally, is at least one of V or T not a defined type? No! Both are defined types. text
is defined by you and string
is defined by the language specs in String types:
> The predeclared string type is string; it is a defined type.
So assigning text
to string
does not meet the conditions for assignability and it gives a compiler error.
答案3
得分: -2
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")
。
英文:
AppendQuote
accept []byte
as argurment and your hello
is defined as text
type which is a []byte
from your type definition, that is why it works.
func strconv.AppendQuote(dst []byte, s string) []byte
see source code
while Quote accepts string as argument,
func strconv.Quote(s string) string
see source code
And your hello type is []byte
, not string. that's why it didn't work. you will either have to use the first case, or change your hello into string. e.g. _ = strconv.Quote("hello")
in order for it to work.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论