Is there a way to create an interface in golang like TypeClasses in Haskell

xuanbao · · 820 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>So let&#39;s say I have the following three interfaces:</p> <pre><code> // StoreInterface is a generic store interface // with methods for basic CRUD operations type StoreInterface interface { Create(interface{}) (interface{}, error) Get(int) (interface{}, error) List(limit, offset int) ([]interface{}, error) Update(interface{}) (interface{}, error) Destroy(int) error } // UserStoreInterface is a store // specifically for users, with the same // CRUD operations as the StoreInterface type UserStoreInterface interface { Create(User) (User, error) Get(int) (User, error) List(limit, offset int) ([]User, error) Update(User) (User, error) Destroy(int) error } // ProductStoreInterface is a store // specifically for Products with the same // CRUD operations as StoreInterface type ProductStoreInterface interface { Create(Product) (Product, error) Get(int) (Product, error) List(limit, offset int) ([]Product, error) Update(Product) (Product, error) Destroy(int) error } </code></pre> <p>These definitions aren&#39;t very DRY. I use almost the same signatures for each of the functions, with only the types changing. Is there a way to define just the StoreInterface and then define UserStoreInterface and ProductStoreInterface in terms of StoreInterface so it would know that I want the same methods with interface{} replaced with a specific type. What I am really looking for is something similar to <a href="http://book.realworldhaskell.org/read/using-typeclasses.html" rel="nofollow">TypeClasses</a> in Haskell.</p> <p>Sorry if this not the type of thing posted here, or if this is a newbie question, I am a newbie to Go. </p> <hr/>**评论:**<br/><br/>shovelpost: <pre><p><a href="https://blog.golang.org/generate" rel="nofollow">Yes</a>, <a href="https://blog.carlmjohnson.net/post/2016-11-27-how-to-use-go-generate/" rel="nofollow">there is a way</a>.</p></pre>itijara: <pre><p>That will work but is much more complicated than I would have hoped. I was hoping I wouldn&#39;t have to resort to a pre-processor or macros. For my use case it is still easier to make a bunch of interfaces. Alternatively, I can use one interface with a bunch of concrete type switches to change the behavior depending on the concrete type.</p></pre>faiface: <pre><p>You can&#39;t really do this nicely in Go. But honestly, I don&#39;t know your specific use-case, but I believe you can rethink your design, so that you don&#39;t have to do this.</p> <p>Beware that you should only use interfaces when polymorphism is required, i.e. when you have more than one (potential) implementation and you have some generic code that accepts this interface.</p></pre>itijara: <pre><p>The use case is that I have handlers that need to get info from different databases depending on the environment (e.g. test, dev). I want to abstract away the database connection using an interface so I can swap out the database without having to change the handler. Using a generic interface works fine usually, but for some of the models I want to do some things like field validation differently than in the generic.</p></pre>Morgahl: <pre><p>Rather then abstracting the objects you are storing, try abstracting the database itself.</p></pre>itijara: <pre><p>Yah, I could do that. It makes more sense. I could pass in a query string and a function for turning the results into the desired struct. Is there a canonical way to do this?</p></pre>_______2: <pre><p>I would take a look at go&#39;s standard library for database access— each context should give you what you&#39;re looking for</p></pre>Hactually: <pre><p>You could always do something like this abomination <a href="https://play.golang.org/p/iKB3b7_P-m" rel="nofollow">https://play.golang.org/p/iKB3b7_P-m</a></p></pre>itijara: <pre><p>Nice. Although I don&#39;t think I want to do something like recreate Javascript in Go.</p></pre>

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

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