为了账号安全,请及时绑定邮箱和手机立即绑定

结构的方法签名之间的区别

结构的方法签名之间的区别

Go
有只小跳蛙 2023-05-15 15:08:38
作为一名来自 C++ 等其他语言的程序员,我觉得很奇怪,go 允许为允许指针或实例作为参数的结构指定方法。根据go by example,如果我们不想修改原点,once 可以使用它们中的任何一个:Go 自动处理方法调用的值和指针之间的转换。您可能希望使用指针接收器类型来避免在方法调用上进行复制或允许该方法改变接收结构。考虑以下代码:package mainimport (    "fmt")type Foo struct {}type Bar struct {}func (this Foo) String() string {  return "Foo"}func (this *Bar) String() string {  return "Bar"}func main() {  fmt.Println(Foo{}) // "Foo"  fmt.Println(Bar{}) // "{}"}为什么我不能同时使用两个签名版本来修改结构的stringify(我不知道它在 go 中实际上是如何调用的)行为?明确一点:我并不真正关心字符串化,但想了解语言的行为方式。
查看完整描述

2 回答

?
汪汪一只猫

TA贡献1898条经验 获得超8个赞

只需添加&Bar{}并使其成为指针接收器,如下所示:

fmt.Println(&Bar{}) // "Bar"

这里对输出的代码进行了一些调整:

Foo
Bar

看:

package main


import "fmt"


type Foo struct{}


func (Foo) String() string {

    return "Foo"

}


type Bar struct{}


func (*Bar) String() string {

    return "Bar"

}


func main() {

    fmt.Println(Foo{}) // "Foo"

    pb := &Bar{}

    fmt.Println(pb) // "Bar"

}

笔记:


收件人姓名应反映其身份;不要使用通用名称,例如“this”或“self”


你的例子不需要名字。


很高兴阅读Golang 方法接收器:


值接收者对原始类型值的副本进行操作。这意味着涉及成本,尤其是在结构非常大的情况下,接收到的指针效率更高。


查看完整回答
反对 回复 2023-05-15
?
幕布斯7119047

TA贡献1794条经验 获得超8个赞

因为 Bar 没有实现stringer*Bar 。

如果您从 Foo 中删除的实现stringer,您将获得“{}”。

同样,当你写fmt.Println(Bar{})它意味着它会寻找类似func (Bar) String()而不是func (*Bar) String()

另外,当你写的时候故事是不同的fmt.Println(&Foo{}),你可能认为它会打印“{}”因为没有func (*Foo) String()但它会打印“Foo”。

为此,您将必须了解接口。这些是我的经验,所以请也做你自己的研究。该fmt.Print函数对传递的参数调用 String()。所以实际上 String() 不是在你的结构上调用的,而是一个类型为 stringer 的变量。

接口类型可以包含一个类型(实现它的)或指向它的指针,如果它是用值接收器实现的。这就是为什么Foo{}两者 &Foo{}都有效。

接口类型只能保存一个类型的指针(实现它的指针),前提是它是用指针接收器实现的。为什么?因为当你实现一个带有指针接收器的接口时,它需要一个只能用指针提供的地址。这就是为什么只&Bar{} 起作用而不起作用的原因Bar{}


查看完整回答
反对 回复 2023-05-15
  • 2 回答
  • 0 关注
  • 114 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信