<p>I haven't seen these features mentioned on this subreddit, so let's talk about them a little!</p>
<p>Method values were introduced in Go 1.1. They allow you to bind a method to a specific object, and then call the method as an ordinary function with the object implied, in a kind of closure.</p>
<p>For example (from "The Go Programming Language"):</p>
<pre><code>type Rocket struct { /* ... */ }
func (r *Rocket) Launch() {}
r := new(Rocket)
time.AfterFunc(10*time.Second, func() {r.Launch()})
</code></pre>
<p>The expression <code>r.Launch</code> creates a method value, binding the Launch function to the specific variable <code>r</code>, giving it a type of <code>func()</code>. So we can just write:</p>
<pre><code>time.AfterFunc(10 * time.Second, r.Launch)
</code></pre>
<p>Method expressions let you transform a method into a function with the receiver as its first argument. So if you defined a <code>Point</code> struct and a method <code>func (p Point) distanceTo(q Point)</code>, you could write Point.distanceTo to get a <code>func(p Point, q Point)</code>. But if the method has a pointer receiver, you need to write <code>(*Type).Method</code> in your method expression.</p>
<p>This is really useful for using methods as first class functions. Using the <a href="https://github.com/andlabs/ui"><code>ui</code> package</a> and the magic of method expressions, I can create a checkbox that disables itself when checked.</p>
<pre><code>package main
import (
"github.com/andlabs/ui"
)
func main() {
err := ui.Main(func() {
window := ui.NewWindow("Method expression demo", 100, 100, false)
box := ui.NewVerticalBox()
myCheckbox := ui.NewCheckbox("I become disabled when checked!")
// Normally this function takes a func(*Checkbox), so
// we transform the method into a function with a method expression
myCheckbox.OnToggled((*ui.Checkbox).Disable)
box.Append(myCheckbox, false)
window.SetChild(box)
window.OnClosing(func(*ui.Window) bool {
ui.Quit()
return true
})
window.Show()
})
if err != nil {
panic(err)
}
}
</code></pre>
<hr/>**评论:**<br/><br/>donatj: <pre><p>I've used this a ton, I wasn't aware that it wasn't there at one point!</p></pre>qaisjp: <pre><p>Hehehe, this feels very Lua-y :D</p>
<p>In Lua, <code>obj:delete()</code> is just syntactic sugar for <code>obj.delete(obj)</code></p></pre>bigpigfoot: <pre><p>thats basically how package net/http implements http.Handle and http.HandleFunc. functions are types too and you pass a handler function with type func(http.ResponseWriter, *http.Request) to your http mux. its definitely an important construct in go.</p></pre>explodes: <pre><p>Interesting for sure. In my wonderful two-week exploration in to Go, I haven't used this yet. Does its practical use come up very often?</p></pre>Smokey_Circles: <pre><p>I might do this for quick implementations of an interface</p></pre>j_d_q: <pre><p>On my phone so can't test it, but would this work on functions that need a pointer receiver? For example, a buffer?</p>
<p>Instead of accepting one-func-interfaces like <code>func ... (r io.Reader)</code> could we do <code>func ... (r ReadFunc)</code>?</p>
<p>Edit: the checkbox example makes it appear so</p></pre>
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传