Syntax question: How does this code work?

blov · · 480 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>I was browsing the source code for <a href="https://github.com/bradfitz/gomemcache" rel="nofollow">gomemcache</a>, and I noticed the following syntax on <a href="https://github.com/bradfitz/gomemcache/blob/19812ca74b7af94a2d363acd8cebbaca8e6006d3/memcache/memcache.go#L499" rel="nofollow">line 499</a>:</p> <pre><code>c.onItem(item, (*Client).set) </code></pre> <p>where <code>set</code> has the signature:</p> <pre><code>func (c *Client) set(rw *bufio.ReadWriter, item *Item) error </code></pre> <p>and <code>onItem</code> has the signature:</p> <pre><code>func (c *Client) onItem(item *Item, fn func(*Client, *bufio.ReadWriter, *Item) error) error </code></pre> <p>As a beginner, I&#39;m obviously missing something, but if <code>fn func(*Client, *bufio.ReadWriter, *Item)</code> receives a <code>*Client</code> as its first parameter, how can we pass <code>(*Client).set</code> to it? What is the difference between passing <code>c.set</code> vs <code>(*Client).set</code> here?</p> <hr/>**评论:**<br/><br/>djherbis: <pre><p>That&#39;s a method expression: <a href="https://golang.org/ref/spec#Method_expressions" rel="nofollow">https://golang.org/ref/spec#Method_expressions</a></p> <p>Whenever you call a method:</p> <p>var a *Client</p> <p>a.set(rw, i)</p> <p>its equivalent to: (*Client).set(a, rw, i)</p> <p>It&#39;s basically calling the method defined on the type with a reference of the type, instead of calling the method from an instance of the type.</p> <p>It works with interfaces too: <a href="https://play.golang.org/p/yAQVBB9Mg3" rel="nofollow">https://play.golang.org/p/yAQVBB9Mg3</a></p></pre>callcifer: <pre><p>Thanks for the explanation! There is <a href="https://www.google.com/search?q=golang+method+expressions" rel="nofollow">very little</a> on Google about this feature, so I guess it isn&#39;t that common.</p></pre>divoxx: <pre><p>You can usually find explanation for most things in the official spec document: <a href="https://golang.org/ref/spec#Method_expressions" rel="nofollow">https://golang.org/ref/spec#Method_expressions</a></p></pre>callcifer: <pre><p>But how do you know what to search for if you have no idea what it&#39;s called? The spec is good for understanding the behaviour of something you&#39;re already aware of, but it feels pretty opaque beyond that. </p></pre>danredux: <pre><p>I just now saw the need for a code &#34;feature explainer&#34;. Like you put in some code and it tells you what features of the language the code is using, perhaps sorted by how common the feature is, then links to relevant docs for each feature.</p></pre>callcifer: <pre><p>That&#39;s a great idea, but sounds very hard to implement, especially if the code you pasted relies on components outside the standard library. Is there anything like that for <em>any</em> language out there?</p></pre>danredux: <pre><p>I don&#39;t believe there is, but it would only work well for language constructs, not external code.</p> <p>It&#39;s not too hard to do, in theory. Take whatever parses the code into an AST, then describe each of the features in that AST. It&#39;s the same as compiling/running the code, but just keeping track of the constructs used.</p> <p>Might be worth trying it out with Python or something and could be very helpful.</p></pre>keks_: <pre><p>You go the Go spec and Ctrl+F for &#34;(T)&#34;, as this is what you see here, a type in parens. The second match looks like your scenario and is indeed in the section &#34;Method Expression&#34;.</p> <p>I didn&#39;t know about this either though. Really interesting.</p></pre>

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

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