对象的字段上调用的方法而不是对象本身?

huangapple go评论80阅读模式
英文:

Method getting called on object's field instead of the object?

问题

这段代码中有一些对象,代表了一个用户和创建该用户的管理员。这是一个申请人提交给我们的代码的简化版本。代码有问题,当你尝试删除用户时(如main中所示),它会删除管理员。为什么u.Delete调用的是管理员的删除方法而不是用户的删除方法?

package admin
import "fmt"
type Admin struct {}
func (Admin) Delete() {
    fmt.Println("deleting admin")
}

package user
import (
    "fmt"
    "admin"
)
type User struct {*admin.Admin}
func (*User) Delete() {
    fmt.Println("deleting user")
}

package main
import (
    "admin"
    "user"
)

func main() {
    u := user.User{&admin.Admin{}}
    u.Delete()
}

$ GOPATH=`pwd` go run a.go 
deleting admin

在代码中,User结构体嵌入了*admin.Admin指针类型,这意味着User结构体继承了Admin结构体的方法。因此,当调用u.Delete()时,实际上是调用了Admin结构体的Delete方法,而不是User结构体的Delete方法。这就解释了为什么会调用管理员的删除方法而不是用户的删除方法。

英文:

This code has some objects representing a user and the admin who created that user. It's a trimmed down version of some code submitted to us by an applicant. The code is broken and deletes the admin when you try to delete the user (as demonstrated by main). Why does u.Delete call the admin's delete instead of the user's delete?

package admin
import "fmt"
type Admin struct {}
func (Admin) Delete() {
    fmt.Println("deleting admin")
}

<!

package user
import (
    &quot;fmt&quot;
    &quot;admin&quot;
)
type User struct {*admin.Admin}
func (*User) D&#120462;lete() {
    fmt.Println(&quot;deleting user&quot;)
}

<!

package main
import (
    &quot;admin&quot;
    &quot;user&quot;
)

func main() {
    u := user.User{&amp;admin.Admin{}}
    u.Delete()
}

<!

$ GOPATH=`pwd` go run a.go 
deleting admin

答案1

得分: 2

因为在用户上定义的删除方法是针对 *User 而不是 User,而 Admin 的删除方法是针对非指针 Admin 定义的。
User 嵌入了 Admin,所以它继承了 func (Admin) Delete() 方法。

尝试使用用户的指针(注意 &

func main() {
    u := &user.User{&admin.Admin{}}
    u.Delete()
}
英文:

because the method delete on the user is defined for *User not for User, while Admin's Delete is defined for the non pointer Admin.
User embeds Admin, so it inherits func (Admin) Delete() method.

try using the pointer to user (notice the &amp;)

func main() {
    u := &amp;user.User{&amp;admin.Admin{}}
    u.Delete()
}

答案2

得分: 1

在你的示例代码中,用户的Delete方法中的字母e的编码与管理员的Delete方法中的字母e不同。由于Go支持utf8,这不是一个错误,但它是一个不同的方法。修复用户的Delete方法中的e,一切应该按预期工作。

英文:

In your sample code the letter e in User's Delete method is not of the same encoding as the letter e in Admin's Delete method. Since Go supports utf8 this is not an error but it is a different method. Fix the e in User's Delete method and all should work as expected.

huangapple
  • 本文由 发表于 2014年9月5日 09:13:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/25677288.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定