<p>I cannot see or understand the benefits of functions with receivers (methods) over simple parameters.</p>
<p>When I see something like this:</p>
<pre><code>package main
import "fmt"
type User struct {
Firstname, Lastname string
}
func (u User) Greeting() string {
return fmt.Sprintf("Dear %s %s", u.Firstname, u.Lastname)
}
func main() {
u := User{"Foo", "Bar"}
fmt.Println(u.Greeting())
}
</code></pre>
<p>I immediately want to do this instead:</p>
<pre><code>package main
import "fmt"
type User struct {
Firstname, Lastname string
}
func Greeting(u User) string {
return fmt.Sprintf("Dear %s %s", u.Firstname, u.Lastname)
}
func main() {
u := User{"Foo", "Bar"}
fmt.Println(Greeting(u))
}
</code></pre>
<p>And the result is exactly the same.</p>
<p>What is the point of receivers in Go?</p>
<hr/>**评论:**<br/><br/>element131: <pre><p>The main reason they are useful is that it is only through receivers that a type can implement an interface. It also allows you to have two functions with the same name that operate on different types.</p></pre>joncalhoun: <pre><p>Another benefit is being able to pass a method around as if it were a function and having the user object available still. You can also achieve this with closures, so methods aren't necessary here, but I prefer to use them. </p>
<p>Eg <code>user.Greeting</code> in the provided example matches <code>func() string</code> whereas the original doesn't, so we could pass it to a function like <code>func a(fn func() string) { ... }</code></p>
<p>On mobile so sorry the example kinda sucks.</p></pre>gohacker: <pre><p>Still another is to be able to pass a variable to a template and invoke its methods for free, without the need of passing a FuncMap when creating the template.</p>
<p><a href="https://play.golang.org/p/lPnc_f_HtF">https://play.golang.org/p/lPnc_f_HtF</a></p></pre>tomcam: <pre><p>Excellent question, absolutely correct answer. Thanks, all!</p></pre>cbarrick: <pre><p>As mentioned, methods enable <em>interface</em> types that allow you to reason about behaviour independent of implementation.</p>
<p>More formally, this pattern is called <a href="https://en.m.wikipedia.org/wiki/Polymorphism_(computer_science">polymorphism</a>) and is a key tenant of object oriented programming and software engineering.</p></pre>HelperBot_: <pre><p>Non-Mobile link: <a href="https://en.wikipedia.org/wiki/Polymorphism_(computer_science" rel="nofollow">https://en.wikipedia.org/wiki/Polymorphism_(computer_science</a></p>
<hr/>
<p><sup>HelperBot</sup> <sup>v1.1</sup> <sup><a href="/r/HelperBot_" rel="nofollow">/r/HelperBot_</a></sup> <sup>I</sup> <sup>am</sup> <sup>a</sup> <sup>bot.</sup> <sup>Please</sup> <sup>message</sup> <sup><a href="/u/swim1929" rel="nofollow">/u/swim1929</a></sup> <sup>with</sup> <sup>any</sup> <sup>feedback</sup> <sup>and/or</sup> <sup>hate.</sup> <sup>Counter:</sup> <sup>26681</sup></p></pre>joncalhoun: <pre><p>Traditional OOP isn't really a great design pattern in Go, so I'm not entirely sure I would use this as a justification for methods.</p></pre>cbarrick: <pre><p>Go is not "classical" OO since there are no classes, but I would argue that it is still OO. Polymorphism, encapsulation, and composition are well supported in the traditional definitions and Go's "type embedding" can be seen as an evolution of classical inheritance.</p>
<p>Go is not Java or C++, but it's still OO IMO.</p></pre>nosmileface: <pre><p>Another not widely used thing about methods. It's the only way to get a list of functions in Go via reflection. You can't get a list of functions in a package, but you can get a list of methods of a type.</p></pre>callcifer: <pre><p>True, but that's more of a downside of the current reflection support than an upside of methods in general.</p></pre>VerilyAMonkey: <pre><p>As others have noted, there are actual functional differences, for example</p>
<ol>
<li>Implement interfaces</li>
<li>Allow you to pass around partially-applied methods that know which struct they came from</li>
<li>List the methods through reflection</li>
<li>Gain access to the methods when you embed the type</li>
</ol>
<p>However, there's another point to be made. What you're saying here is actually equally true in virtually every object oriented language. Java and C++, methods are like a Go method with a pointer receiver named "this". Python, methods take in "self" as a first, automatically populated parameter, also essentially a pointer receiver. So there is also an answer which is... Whatever reason there is to have methods in other languages.</p></pre>yamiodymel: <pre><p>Sometimes you can just do:</p>
<pre><code>u := User{"Foo", "Bar"}
p := Post{"Hello", "World"}
u.Create()
p.Create()
</code></pre>
<p>instead of</p>
<pre><code>u := User{"Foo", "Bar"}
p := Post{"Hello", "World"}
CreateUser(u)
CreatePost(p)
</code></pre></pre>
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传