You can add a method to a function!

agolangf · · 459 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<pre><code>package main import &#34;fmt&#34; type Fn func(string)(int) func (f Fn) glork(s string) int { fmt.Printf(&#34;Reached glork(%q)\n&#34;, s) x := f(s) return x } func example(s string) int { fmt.Printf(&#34;Reached example(%q)\n&#34;, s) return len(s) } func main() { var fx Fn fx = example // This assignment makes it work. n := fx.glork(&#34;calling glork&#34;) fmt.Printf(&#34;Got back %d from calling fx.glork()\n&#34;, n) } </code></pre> <hr/>**评论:**<br/><br/>robpike: <pre><p>See the explanation of HandlerFunc in <a href="https://golang.org/doc/effective_go.html">https://golang.org/doc/effective_go.html</a>, which is just <a href="https://golang.org/pkg/net/http/#HandlerFunc">https://golang.org/pkg/net/http/#HandlerFunc</a>.</p></pre>IanS_5: <pre><p>That&#39;s an interesting way to implement it. I kinda want to try something like that now :P</p></pre>chmikes: <pre><p>What is the purpose of this construct ? No web programming tutorial or book I could find explains the purpose of HandlerFunc. </p></pre>cavaliercoder: <pre><p>In the context of HTTP handlers, one benefit is that you can implement the <code>http.Handler</code> interface simply by wrapping a function with <code>HandlerFunc</code>. Alternatively, you would have to define a struct (probably empty) and adorn it with your function implementation.</p> <p>You can also create your own handler call signatures (maybe to include request, response writer and a db connection or next middleware) and conveniently wrap them for consumption by the http stdlib. Negroni does this. <a href="https://github.com/urfave/negroni">https://github.com/urfave/negroni</a></p></pre>mcouturier: <pre><p>If the interface you want to implement only has one function and likely no state, instead of defining an empty struct that implement that interface, a HandlerFunc is provided to implement that interface solely by providing a function. This is a time saving technique to implement an interface that has one function using a function.</p> <p>I know I said function a lot :)</p></pre>earthboundkid: <pre><p>It lets you decide if you want to use a type+method to implement the <code>ServeHTTP</code> method and thereby implement the <code>Handler</code> interface, or just make a quick function to implement it. It adds flexibility to the architecture.</p></pre>lattakia: <pre><p>Are you the Rob Pike that I think you are ?</p></pre>eggnot: <pre><p>Idea: create grammar/vocabulary profile based on known Rob Pike sources, then plug in comment history of this account to generate confidence rating. Even if it&#39;s not Rob, and they&#39;re just really good at pretending to be him, you can just act like it is and refer back to your confidence rating if that&#39;s ever called into question.</p> <p>Who needs truth when you have math?</p></pre>TangZero: <pre><p>Yes we can!</p></pre>ianbezo: <pre><p>Yes. For the full picture this example is missing an interface because this is especially useful in combination with a <strong>single function interface</strong> (like http.Handler). With this pattern in order to write various handlers implementations we don&#39;t need to create named struct for every case. It&#39;s enough to write a function and wrap it in the adapter (like http.HanderFunc, in the example above Fn).</p></pre>gentleman_tech: <pre><p>functions are first-class types. No different from strings, integers, structs, or maps. You can add methods to all of them, too :)</p></pre>jocull: <pre><p>Is they considered dirty, like changing the primitive prototypes in JS?</p></pre>Redundancy_: <pre><p>You can&#39;t do </p> <pre><code>func (s string) Foo() { } </code></pre> <p>You have to have a local type to do it, so you&#39;re never adding methods a type that&#39;s not from your package. What you can do is create a new type that&#39;s analagous:</p> <pre><code>type Goo string func (s Goo) Foo() { //valid } </code></pre> <p>So there&#39;s nothing dirty involved.</p></pre>gentleman_tech: <pre><p>what they said :)</p> <p>in fact, this is generally looked on as A Good Thing.</p></pre>lattakia: <pre><p>So creating new types with <code>type</code> is not just aliasing ?</p></pre>carsncode: <pre><p>Not <em>just</em> aliasing, no. When you create a new type this way, any methods that exist for the base type are not available on the new type, but new methods can be attached to the new type. There&#39;s also no implicit casting, only explicit casting, making it even less alias-like, and making it useful for things like enumerations.</p></pre>Redundancy_: <pre><p><a href="https://golang.org/ref/spec#Type_declarations" rel="nofollow">https://golang.org/ref/spec#Type_declarations</a></p> <p>It an take a bit of work to understand clearly, but:</p> <pre><code>type A string func (a A) Foo() {} func S(s string){} type B A // B does not have Foo() // You cannot use B in S(...) // You CAN convert B to string or A </code></pre></pre>dilap: <pre><p>Nope, it creates a new type. This is actually handy for getting type errors on purpose when mixing up types.</p> <p>E.g., </p> <blockquote> <p>type FooId uint32</p> </blockquote> <p>or whatever.</p> <p>The next version of Go will add aliases:</p> <blockquote> <p>type OtherInt = int</p> </blockquote> <p>OtherInt and int will be two different ways to write down the same type.</p></pre>bupku5: <pre><p>yes this is basically how http handlers are structured...it really feels like this feature was added to address some brittleness in the applicability of the handler interface</p></pre>robpike: <pre><p>Not at all. It&#39;s not even a feature, just something that fell out of an orthogonal language design. Any concrete type can have a method. A function is a concrete type. Therefore functions can have methods.</p></pre>negbie: <pre><p>Not so unusual when u are working with json and you want to implement the marshaller for your own types.</p> <p>func (y *YourType) MarshalJSON() ([]byte, error) { </p></pre>

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

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