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

科技回声

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

GitHubTwitter

首页

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

资源链接

HackerNews API原版 HackerNewsNext.js

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

A theory of modern Golang

130 点作者 imwally将近 8 年前

13 条评论

chubot将近 8 年前
In other words, use a pure dependency-injection style, and ZERO globals.<p>I&#x27;m writing Python and some C++, and I have been doing this for maybe 5-6 years. It takes a little practice to structure your programs like this, but once you know how, it has a lot of benefits.<p>It&#x27;s not really idiomatic in those communities either. Python and C++ Libraries use globals all the time, although I think it&#x27;s becoming less common.<p>I guess Java programmers have been doing dependency injection for even longer. It probably became popular more than 10 years ago. But I&#x27;m not really sure how &quot;pure&quot; the Java ecosystem is. Singletons are banned under this style. Instead, a singleton is just an object you instantiate once in main(), and pass throughout the rest of your program.<p>I think the problem with Java is lack of free functions. Static methods confuse things too.<p>The pure-dependency injection style is basically <i>functional programming</i>, requiring state as an explicit parameter.
评论 #14525044 未加载
评论 #14524322 未加载
评论 #14525739 未加载
评论 #14524040 未加载
评论 #14524221 未加载
评论 #14523895 未加载
评论 #14525792 未加载
JBReefer将近 8 年前
This is basically &quot;Use DI, and move towards SOLID&quot;<p>Well, yeah! Those are great principles in any language - I find it concerning (and maybe indicative of something) that the Go community has voted this up. These are fundamental requirements to building testable, scalable systems in teams. Having global variables has been bad practice for what, 20 years? One of the first lines in Javascript, the Good Parts (closest book handy) is:<p><pre><code> JavaScript is built on some very good ideas and a few very bad ones. ... The bad ideas include a programming &gt;model based on global variables.</code></pre>
评论 #14525176 未加载
评论 #14524949 未加载
评论 #14525682 未加载
obstinate将近 8 年前
I don&#x27;t think, in the limit, that this is a scalable approach. While I think injecting dependencies is fine in some cases, large programs might have hundreds or thousands of collaborators. It is simply not feasible to instantiate all of them in the main function then pipe all of them down to the package that uses them. This is especially true when you keep the interface small like this program seems to.<p>I think making the dependency explicit is good when it is likely that it is going to be desired to change the implementation on a per object basis. If it&#x27;s unlikely or meaningless to have multiple different implementations within the same process, there&#x27;s nothing wrong with making the configuration global.<p>Imagine how painful it would be to use the http module if it required the injection of its clock, compression suite, network interfaces, address resolvers, loggers, etc. And that&#x27;s just one module of many.
jimrandomh将近 8 年前
I think the author&#x27;s two examples - a logger and a database connection - should be handled differently from each other. The database connection should be passed as a parameter, and the logger should be a global variable.<p>One difference is that it&#x27;s reasonable to add logging to nearly any function anywhere, which means that you have to either make the logger global, preemptively provide a logger parameter to almost everything, or else change a whole bunch of method signatures at once every time you need to add logging to somewhere that didn&#x27;t previously have any log statements. Global variables are unfortunate, but the other options are much worse.<p>The second difference is that you pretty much only ever have one logger object in a process, but processes often use multiple database connections and it may matter which one is being used. For example, a caller may want to make your function&#x27;s database accesses part of its transaction. Or use a unit test database instead of a real database. Or a number of other things. Omitting the parameter hides the fact that a function uses the database, which is an important thing to know about it.
评论 #14525381 未加载
weberc2将近 8 年前
I agree with every bit of this, especially with constructors taking their dependencies explicitly. In fact, I try to write my Go code in such a way that constructors aren&#x27;t needed (sometimes this can&#x27;t be helped) so the &quot;constructor&quot; is simply a type initialization expression `foo := Foo{Bar: 7}`. This keeps everything simple and testable.
评论 #14524166 未加载
weitzj将近 8 年前
I favor an DI style as well, but sometimes in rare cases I like using the init functions.<p>This boils down to functions which follow the template.Must pattern, i.e.: either the function can be evaluated or the program should panic.<p>The other case is read-only lookup tables.
transitorykris将近 8 年前
I&#x27;ve recently been bit by global state that used function initializers (func init() isn&#x27;t the only way to execute logic when a package is imported!). The package used very reasonable defaults, but panic()&#x27;d when things didn&#x27;t look right. So, forking, maintaining patches until upstream changes the behavior, painful.
评论 #14524527 未加载
linkmotif将近 8 年前
&gt; &quot;modern Go&quot;<p>The language was first released in 2007 :). Man...
评论 #14524102 未加载
DAddYE将近 8 年前
This isn&#x27;t &quot;modern go&quot; but more the &quot;standard&quot; in any language.
评论 #14525714 未加载
marcus_holmes将近 8 年前
The stdlib does include some globals&#x2F;statics, for good reasons (the default logger, the default http mux).<p>I&#x27;m always wary about advice that says &quot;you must never use {this tool provided by a language}&quot;. Never say never ;)<p>Globals can be and are useful in some circumstances. Having a blanket ban on globals because &quot;globals are bad mmkay&quot; is not useful.<p>I draw this line at &quot;do I need to mock this for testing?&quot;. If I need to mock it to run tests, then it shouldn&#x27;t be a global and should be DI&#x27;d (so I can DI the mock). If I&#x27;m not going to mock it, then it&#x27;s probably fine to leave it as a global.<p>The Db and Logger are perfect examples: I frequently mock the Db connection, so I can test sql output. I almost never mock the logger, because I only use it to output meta information. So having a global logger is OK.<p>YMMV...
评论 #14525999 未加载
tagrun将近 8 年前
The author is basically complaining that Go (and its standard library) isn&#x27;t functional.
bitwize将近 8 年前
An internet discovers dependency injection. Hackernews responds, &quot;Well of course we knew THAT.&quot; The Rust Evangelism Strikeforce is off on a secret mission in the Balkans.
评论 #14525069 未加载
评论 #14525058 未加载
mourner将近 8 年前
Expected to see an article about the development of modern Go the board game theory after the advent of AlphaGo and AI generally. Got disappointed. Happens every time :(
评论 #14524946 未加载
评论 #14524211 未加载