英文:
How can I define an implementation of Go interface method that receives pointer?
问题
以下是翻译好的内容:
以下程序运行正常。
package main
import (
"fmt"
)
type Person interface {
Hello()
}
type Joker struct {
Name string
}
func (j Joker) Hello() {
fmt.Println(j.Name, "says, \"Hello!\"")
}
func main() {
var j Joker = Joker{"Peter"}
invokeHello(j)
}
func invokeHello(p Person) {
p.Hello()
}
以下是输出结果。
$ go run foo.go
Peter says, "Hello!"
但是当我将Hello
方法改为接收一个指针时,就会出现错误。
package main
import (
"fmt"
)
type Person interface {
Hello()
}
type Joker struct {
Name string
}
func (j *Joker) Hello() {
fmt.Println(j.Name, "says, \"Hello!\"")
}
func main() {
var j *Joker = &Joker{"Peter"}
invokeHello(j)
}
func invokeHello(p *Person) {
p.Hello()
}
以下是错误信息。
$ go run bar.go
# command-line-arguments
./bar.go:21: cannot use j (type *Joker) as type *Person in argument to invokeHello:
*Person is pointer to interface, not interface
./bar.go:25: p.Hello undefined (type *Person has no field or method Hello)
我该如何修复第二个程序?
英文:
The following program runs fine.
package main
import (
"fmt"
)
type Person interface {
Hello()
}
type Joker struct {
Name string
}
func (j Joker) Hello() {
fmt.Println(j.Name, "says, \"Hello!\"")
}
func main() {
var j Joker = Joker{"Peter"}
invokeHello(j)
}
func invokeHello(p Person) {
p.Hello()
}
Here is the output.
$ go run foo.go
Peter says, "Hello!"
But when I change the Hello
method to receive a pointer, I get errors.
package main
import (
"fmt"
)
type Person interface {
Hello()
}
type Joker struct {
Name string
}
func (j *Joker) Hello() {
fmt.Println(j.Name, "says, \"Hello!\"")
}
func main() {
var j *Joker = &Joker{"Peter"}
invokeHello(j)
}
func invokeHello(p *Person) {
p.Hello()
}
Here are the errors.
$ go run bar.go
# command-line-arguments
./bar.go:21: cannot use j (type *Joker) as type *Person in argument to invokeHello:
*Person is pointer to interface, not interface
./bar.go:25: p.Hello undefined (type *Person has no field or method Hello)
How can I fix the second program?
答案1
得分: 3
func invokeHello(p *Person) {
p.Hello()
}
p
是类型 *Person
,*Joker
实现了接口 Person
,将 invokeHello
修改为:
func invokeHello(p Person) {
p.Hello()
}
这样可以修复第二个程序。
我认为你对 golang 接口类型 有一些误解。
接口类型指定了一个称为其接口的方法集。接口类型的变量可以存储具有方法集的任何超集的任何类型的值。这样的类型被称为实现了该接口。
英文:
func invokeHello(p *Person) {
p.Hello()
}
p
is type *Person
, *Joker
implement interface Person
, revert invokeHello
to:
func invokeHello(p Person) {
p.Hello()
}
this will fix the second program.
I think you have misleading about golang interface type
> An interface type specifies a method set called its interface. A variable of interface type can store a value of any type with a method set that is any superset of the interface. Such a type is said to implement the interface.
答案2
得分: 0
修复
你不能使用指向interface
类型的指针。
问题在于:
func invokeHello(p *Person) {
p.Hello()
}
应该改为:
func invokeHello(p Person) {
p.Hello()
}
接口实现
类型实现接口。如果类型具有与接口声明的方法相匹配的方法,那么该类型就实现了该接口。
> 在Go中,接口提供了指定对象行为的方式:如果某个东西可以做到这一点,那么它就可以在这里使用。
类型 vs 类型的指针
Type
和*Type
是不同的类型。例如,*Type
可以实现一个接口,但Type
不能实现它。但是*InterfaceType
在使用上确实没有意义。
如果你想在一个期望接口类型的函数中接收一个类型的指针,可以使用指针接收器来实现接口,就像你在第二个示例中所做的那样。
示例:
type Person interface {
Hello()
}
type Joker struct {
Name string
}
/*
Hello方法使用指针接收器声明,这意味着指向Joker类型(*Joker)的指针而不是Joker类型本身实现了Person接口。
*/
func (j *Joker) Hello() {
fmt.Println(j.Name, "says, \"Hello!\"")
}
/*
invokeHello接收满足Person接口的任何类型。
在这种情况下,传入的是Joker类型的指针。
*/
func invokeHello(p Person) {
p.Hello()
}
func main() {
i := Joker{"Peter"}
j := &i
// 注意类型之间的差异
fmt.Printf(
"Joker类型:%s\nJoker类型的指针:%s\n",
reflect.TypeOf(i), reflect.TypeOf(j))
invokeHello(j)
}
否则,如果你想接收一个类型的值,请使用值接收器来实现接口,就像你在第一个示例中所做的那样。
英文:
Fix
You can't use pointers to interface
type.
That is the problem:
func invokeHello(p *Person) {
p.Hello()
}
Should be:
func invokeHello(p Person) {
p.Hello()
}
Interface implementation
Types implement interfaces. If type has methods appropriate to a methods declared in an interface than the interface is implemented by the type.
> Interfaces in Go provide a way to specify the behavior of an object: if something can do this, then it can be used here.
Types vs pointers to a types
Type
and *Type
are different types. For example *Type
could implement an interface but Type
can not implement it. But *InterfaceType
really has no sence to use.
If you want to receive pointer to a type in a function which expects an interface type, implement the interface with pointer receiver, like you did in a second example.
type Person interface {
Hello()
}
type Joker struct {
Name string
}
/*
A Hello method declared with a pointer receiver which means that a pointer to
the Joker type (*Joker) not Joker type itself implements Person interface.
*/
func (j *Joker) Hello() {
fmt.Println(j.Name, "says, \"Hello!\"")
}
/*
invokeHello receives ANY type which statisfies Person interface.
In this case this is pointer to Joker type.
*/
func invokeHello(p Person) {
p.Hello()
}
func main() {
i := Joker{"Peter"}
j := &i
// Note difference between types
fmt.Printf(
"Joker type: %s\nPointer to Joker type: %s\n",
reflect.TypeOf(i), reflect.TypeOf(j))
invokeHello(j)
}
Otherwise if you want to receive a value of a type, implement the interface with value receiver, like you did in a first example.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论