英文:
Ambiguous Conversion Syntax in Go
问题
我有以下类型定义:
type reader io.Reader
我希望这个 reader
类型实现 io.Reader
接口,所以我这样做:
func (r reader) Read(p []byte) (n int, err error) {
return io.Reader(r).Read(p)
}
问题是:io.Reader(r)
可能有两种含义:
- 将
r
转换为其底层类型(io.Reader
) - 静态断言(由编译器检查)
r
满足io.Reader
接口(因为我们定义了一个Read([]byte) (int, error)
方法,它满足接口)。创建一个新的io.Reader
接口值并将r
存储在其中。
我希望发生前者。如果发生后者,当我调用 io.Reader(r).Read(p)
时,它将调用 r
的底层 Read
方法(我们此刻正在其中),并且会无限循环。我希望发生的是提取 r
内部的底层 io.Reader
,并使用它的 Read
方法。
当然,我可以通过实际测试来确定这两种情况中的哪一种发生,但我对 Go 编译器如何解决这些问题感到好奇。我在语言规范中找不到相关信息。
英文:
I have the following type definition:
type reader io.Reader
and I want this reader
type to implement the io.Reader
interface, so I do:
func (r reader) Read(p []byte) (n int, err error) {
return io.Reader(r).Read(p)
}
The problem is this: io.Reader(r)
could mean one of two things:
- Convert
r
to its underlying type (io.Reader
) - Assert statically (checked by compiler) that
r
satisfies theio.Reader
interface (since we've defined aRead([]byte) (int, error)
method, it does). Create a newio.Reader
interface value and storer
inside it.
I want the former to happen. If the latter happens, when I call io.Reader(r).Read(p)
, it will call r
's underlying Read
method (which we are inside at the moment), and it will infinite loop. What I would like to happen is to extract the underlying io.Reader
inside r
, and use its Read
method.
Of course, I could just test to see in practice which of the two of these happens, but I'm curious in general about how these problems are resolved by the Go compiler. I couldn't find the relevant information in the language spec.
答案1
得分: 9
你不能将接口类型reader
(定义为io.Reader
)用作func (r reader) {}
中的接收器类型。
你需要将reader
类型定义为一个具体类型:
type reader struct {
// stuff
}
回答你的问题,io.Reader(r)
的意思是在编译时断言r
满足io.Reader
接口,并创建一个新的io.Reader
接口值,并将r
存储在其中(你的第二个选择)。
因此,如果你尝试上述操作,将会导致无限递归。
在Go语言中,底层的io.Reader
的概念是没有意义的,因为你不能在接口上定义方法,只能在具体类型上定义方法。
当然,你可以在彼此之间嵌入类型,可能会像这样:
type reader struct {
other io.Reader
}
然后你可以调用:
func (r reader) Read(p []byte) (n int, err error) {
return r.other.Read(p)
}
英文:
You can't use an interface type reader
which is defined as io.Reader
as a receiver type in func (r reader) {}
.
You need to define the reader type as a specific type
type reader struct {
// stuff
}
To answer your question, the io.Reader(r)
means assert at compile time that r
satisfies the io.Reader
interface and create a new io.Reader
interface value and store r
inside it. (your second choice).
So if you try the above you'll get an infinite recursion.
The idea of an underlying io.Reader
makes no sense in Go since you can't define methods on interfaces, only on concrete types.
You can of course embed types within each other which might look like this
type reader struct {
other io.Reader
}
Which you would then call
func (r reader) Read(p []byte) (n int, err error) {
return r.other.Read(p)
}
答案2
得分: 0
我认为接收器方法只适用于结构体,此外,你正在尝试将一个接口实现为另一个接口。我不知道在Go语言中是否可能实现这一点。在其他语言中,比如Java,可以通过抽象类来解决这个问题,但是Go语言的核心中没有这个概念。
英文:
I think that the receiver method is only for Struct, Furthermore you are trying to implement one interface to another interface. I dont know if this is posible in go. In other languages like Java that implementation is solved with abstract class but GoLang do not have this topics in your core.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论