TE
科技回声
首页24小时热榜最新最佳问答展示工作
GitHubTwitter
首页

科技回声

基于 Next.js 构建的科技新闻平台,提供全球科技新闻和讨论内容。

GitHubTwitter

首页

首页最新最佳问答展示工作

资源链接

HackerNews API原版 HackerNewsNext.js

© 2025 科技回声. 版权所有。

Decorators in Go using embedded structs

95 点作者 fabianlindfors超过 5 年前

7 条评论

AYBABTME超过 5 年前
Embedding like this will only lead to pain long term. It&#x27;s preferable to implement the interface you want to fulfil directly (by having actual method definitions), despite the extra ceremony. Inheritance with embedding is a false friend in Go. Stick to composition.<p>If you want to delegate a call to a &quot;subtype&quot;, simply invoke the method on the subtype by writing it out in long form. It doesn&#x27;t make you feel as intelligent but it&#x27;s way more robust and won&#x27;t come back to bite you down the line.
评论 #21337290 未加载
评论 #21337079 未加载
评论 #21338035 未加载
评论 #21337292 未加载
avita1超过 5 年前
I find the comparison to java a bit unfair, because this pattern is totally possible but has been largely deemed a bad pattern. The analog to the pattern in java is to extend from a non-final class. So in this case &quot;class HTTPClient&quot; and &quot;class CachedHTTPClient&quot;.<p>There are lots of drawbacks to doing it that way, the worst of which is that you need to remember to override the method in CachedHTTPClient everytime you add a method to HTTPClient, and the compiler gives you no hints about it.
评论 #21335657 未加载
评论 #21336414 未加载
评论 #21335648 未加载
评论 #21335266 未加载
评论 #21335283 未加载
inlined超过 5 年前
This is a bad practice in Go for any interface type. Interfaces which are wrapped will fail all type assertions against their original type and fail to assert into additional interfaces that the original also implemented.<p>For example, imagine you have an io.Reader. It may actually implement io.ReaderTo which is used in some cases to implement alloc-free copying. If you wrap it into a new struct, e.g. ioutil.NopCloser you delegate the main interface but not the bonus interfaces. You can no longer cast to the type of the original reader interface either (concrete type comparison is more important with errors, which had a custom fix in Go just for this)
评论 #21336035 未加载
评论 #21337271 未加载
avalanche123超过 5 年前
This pattern is called Composition (<a href="https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Composition_over_inheritance" rel="nofollow">https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Composition_over_inheritance</a>). What makes it much more practical in Go than in say Java is struct embedding and implicit interface implementations
评论 #21335516 未加载
评论 #21336460 未加载
pram超过 5 年前
A small critique on your examples: you never actually show using the Client interface anywhere. Might be useful to someone new to see how you&#x27;d switch out HTTPClient for CachedHTTPClient using it.
评论 #21337072 未加载
ljm超过 5 年前
There’s probably more but the singular best use-case I’ve found for embedding a struct is when you want a mutex.<p>That is elegant.<p>This example looks nice, but I think the naming of the structure and interfaces makes it hard to follow and a cache doesn’t necessarily benefit from it. In fact, it’s worse if your cache isn’t in-memory, and you’re not sharing an instance or a connection pool. If you are, this is just indirection and you can live with `Cache.get` just as well.
评论 #21337912 未加载
yepthatsreality超过 5 年前
I think this is also a good primer into golang inheritance and composition, which are major concepts in successful golang programming.
评论 #21335532 未加载
评论 #21335678 未加载