<p>So let'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'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'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't really do this nicely in Go. But honestly, I don't know your specific use-case, but I believe you can rethink your design, so that you don'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's standard library for database access— each context should give you what you'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't think I want to do something like recreate Javascript in Go.</p></pre>
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传