Method values and method expressions are pretty cool.

blov · · 392 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>I haven&#39;t seen these features mentioned on this subreddit, so let&#39;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 &#34;The Go Programming Language&#34;):</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 ( &#34;github.com/andlabs/ui&#34; ) func main() { err := ui.Main(func() { window := ui.NewWindow(&#34;Method expression demo&#34;, 100, 100, false) box := ui.NewVerticalBox() myCheckbox := ui.NewCheckbox(&#34;I become disabled when checked!&#34;) // 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&#39;ve used this a ton, I wasn&#39;t aware that it wasn&#39;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&#39;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&#39;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

392 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传