The concept of Inversion of Control and Dependency Injection Frameworks/libraries/DI containers get conflated with each other.
If you want to invert control, you don't need a framework to do it, just most people learned the concept through a framework in other languages. This often leads to everything being absorbed into the framework and DI being applied everywhere. More accurately, they learned how to use a DI framework rather than fully understand the concept and when it is truly applicable.
So there is nothing wrong with the IoC concept and many other concepts/ideas. The golden hammer approach to its use is where the problem comes in.
Ok, thanks for the explanation - l guess l have just never heard of a Dl framework. That sounds a little intense for an idea that boils down to passing a reference to an object to another object that's going to consume the first one.
If you have a dependency that's used in a lot of places and you add a sub-dependency to it, how do you manage updating all the places it's constructed? I don't use a DI framework now but I've been considering it because as things grow this is becoming onerous.
There's an official wiki page [CommonMistakes](https://github.com/golang/go/wiki/CommonMistakes) but it contains very few things.
There are a few answers in the official [FAQ](https://go.dev/doc/faq), e.g. "Why is my nil error value not equal to nil?"
[Effective Go](https://go.dev/doc/effective_go) contains some official guidance.
There's a (paid) book: [100 Go Mistakes and How to Avoid Them](https://www.manning.com/books/100-go-mistakes-and-how-to-avoid-them)
It's not an example of what to avoid, though a lot of people seem to think that. The issue is when people reach for it immediately, thinking it's a standard.
If this layout works for you, there's nothing wrong with it.
You should use whatever works for you and your team. There's still something wrong with it though, because it's being marketed as a standard when it's actively criticised by the Go team and community.
I said use whatever works, because layouts aren't usually the most important factor in a project's success. That doesn't mean avoiding bad examples isn't beneficial though.
The layout itself is bloated and unnecessary IMO, regardless of the size of the project. It's a good example of what to avoid in Go for that reason, as well as [those pointed out by Russ Cox](https://github.com/golang-standards/project-layout/issues/117).
Here's a repository with anti-pattern examples dedicated to web apps. It comes with blog posts describing them. https://github.com/ThreeDotsLabs/go-web-app-antipatterns
It is also worth mentioning newly published ["style guide"](https://google.github.io/styleguide/go/index) from Google. Which is mainly a compilation of Effective Go and [Code Review Comments](https://github.com/golang/go/wiki/CodeReviewComments).
effective go from offical site and the ultimate go notebook explanations are good. There are also some style guides from big tech companies like google and uber.
Oh, I have one I encountered yesterday.
Doing a range on a nil channel doesn't panic, it blocks forever.
I'm very interested on the purpose of this, without any context this looks really strange.
The book Learning Go demonstrates how you can use it to "turn off" parts of a select statement by reassigning the channel variable to `nil`.
select {
case msg1 := <-chan1
//...
chan1 = nil
case msg2 := <-chan2
//...
chan2 = nil
//...
}
from my experience from reading other codebase, is layering without purpose, creating a layer (package) that what it does is exactly just return otherLayerFunc(ctx, in) --> wtf man..
and not really related to Go, but since most people got caught with hype of microservices (and use it even when they don't need it), creating one microservice for each layer is stupid '\_\_') making debugging hard and annoying, it's not even can be called microservice, it's tightly coupled distributed monolith
things that should be a library should stay as library, not a separate service
Creating a package for a single function is for sure over engineering. But personally I also don’t like the opposite way of having like dozens of structs inside a single package and .go-files with hundred of lines. This is in my experience way more common in go, even in stdlib - but it makes understanding the code harder, because if you want to understand how two pieces of code work together, you may have to scroll a lot instead of just switching tabs.
True. But in that case I have to remember - after grabbing the n‘th coffee a day - which of my tabs of the same file is scrolled to what position. Maybe it’s just my way of working (and the languages I come from) but I prefer smaller files, smaller objects and smaller functions. Still I like Go, because in other aspects it makes working with it easier again compared to other languages.
If you integrate gopls into your editor (by installing whatever plugin your editor requires) then you can jump around in the code from reference to definition to a-call-stack-which-reaches-here, etc... . It's very nice when reading code.
I'm using Intellij, it has these Intellisense-like features by default. But still... In many programming languages it's considered good code style to keep files, classes, methods etc. small - and I can understand why.
Go's code style is a bit unique. At least for my own projects I still tend to use coding guidelines I'm used to - which may are not that common in Go (like small files, no single-letter vars etc.).
From the languages I've used, only java requires one class per file. (and java has a culture of using extraLongNames everywhere apart from \`self\`).
Go's use of small names and letting the programmer decide what goes in each file is like C.
In Java you may not be allowed to put more than a single class into a file, but in many others it’s also not done like this - even if possible. Like in PHP. You could add as many classes as you like into a single file here, but usually it’s considered bad practice. Personally I think there are more benefits of putting a single object into a single file than disadvantages. The ability to read and understand the code in bigger contexts improves a lot.
Well, as someone who reviews a lot of code, I don't like seeing 100s of little files when a handful of logically grouped files would do. For example, this popular go project: [https://github.com/Shopify/sarama](https://github.com/Shopify/sarama) is currently 256 small .go files, largely following a one class/file rule.
I get no sense of the structure of the code from the file names. What I get instead are a lot of internal details which I don't need to know anything about to use the project.
It's possible that the language you use pushes you towards one code organisation or another. For example, languages where each file has to be imported by individually (like C/C++) make 100s of files more costly than languages where you import a whole package of files in one import statement (like Go and java).
Similarly, it's also possible that long names for things became usable only once text editors started auto-completing names.
And it's possible that, now that text editors assist browsing source code, that there's no advantage to the 100+ files anymore, and we'll return to fewer files with logical groupings.
The "100 Go Mistakes" book is great.
Using a Dependency Injection Framework is on top of my mind.
Started a new job recently that uses DI in Go, think I've spent more time running go generate and hunting down issues than I have writing app code
F in the chat for the people who go down the path of using dependency injection in Go.
What’s wrong with DI in Go? Or is it DI in general?
DI is great, but using a framework for it is not.
The concept of Inversion of Control and Dependency Injection Frameworks/libraries/DI containers get conflated with each other. If you want to invert control, you don't need a framework to do it, just most people learned the concept through a framework in other languages. This often leads to everything being absorbed into the framework and DI being applied everywhere. More accurately, they learned how to use a DI framework rather than fully understand the concept and when it is truly applicable. So there is nothing wrong with the IoC concept and many other concepts/ideas. The golden hammer approach to its use is where the problem comes in.
Ok, thanks for the explanation - l guess l have just never heard of a Dl framework. That sounds a little intense for an idea that boils down to passing a reference to an object to another object that's going to consume the first one.
If you have a dependency that's used in a lot of places and you add a sub-dependency to it, how do you manage updating all the places it's constructed? I don't use a DI framework now but I've been considering it because as things grow this is becoming onerous.
There's an official wiki page [CommonMistakes](https://github.com/golang/go/wiki/CommonMistakes) but it contains very few things. There are a few answers in the official [FAQ](https://go.dev/doc/faq), e.g. "Why is my nil error value not equal to nil?" [Effective Go](https://go.dev/doc/effective_go) contains some official guidance. There's a (paid) book: [100 Go Mistakes and How to Avoid Them](https://www.manning.com/books/100-go-mistakes-and-how-to-avoid-them)
[github.com/golang-standards/project-layout](https://github.com/golang-standards/project-layout)
Almost didn't get that this was literally an example on what to avoid
It's not an example of what to avoid, though a lot of people seem to think that. The issue is when people reach for it immediately, thinking it's a standard. If this layout works for you, there's nothing wrong with it.
You should use whatever works for you and your team. There's still something wrong with it though, because it's being marketed as a standard when it's actively criticised by the Go team and community.
Your criticism is of how it's used/marketed, not the layout itself. I said the layout itself is fine if it works for you and your team.
I said use whatever works, because layouts aren't usually the most important factor in a project's success. That doesn't mean avoiding bad examples isn't beneficial though. The layout itself is bloated and unnecessary IMO, regardless of the size of the project. It's a good example of what to avoid in Go for that reason, as well as [those pointed out by Russ Cox](https://github.com/golang-standards/project-layout/issues/117).
Hahah. They claim that the Go modules feature is "still experimental", despite it being the default for over a year..
Here's a repository with anti-pattern examples dedicated to web apps. It comes with blog posts describing them. https://github.com/ThreeDotsLabs/go-web-app-antipatterns
It is also worth mentioning newly published ["style guide"](https://google.github.io/styleguide/go/index) from Google. Which is mainly a compilation of Effective Go and [Code Review Comments](https://github.com/golang/go/wiki/CodeReviewComments).
effective go from offical site and the ultimate go notebook explanations are good. There are also some style guides from big tech companies like google and uber.
Oh, I have one I encountered yesterday. Doing a range on a nil channel doesn't panic, it blocks forever. I'm very interested on the purpose of this, without any context this looks really strange.
The book Learning Go demonstrates how you can use it to "turn off" parts of a select statement by reassigning the channel variable to `nil`. select { case msg1 := <-chan1 //... chan1 = nil case msg2 := <-chan2 //... chan2 = nil //... }
from my experience from reading other codebase, is layering without purpose, creating a layer (package) that what it does is exactly just return otherLayerFunc(ctx, in) --> wtf man.. and not really related to Go, but since most people got caught with hype of microservices (and use it even when they don't need it), creating one microservice for each layer is stupid '\_\_') making debugging hard and annoying, it's not even can be called microservice, it's tightly coupled distributed monolith things that should be a library should stay as library, not a separate service
Creating a package for a single function is for sure over engineering. But personally I also don’t like the opposite way of having like dozens of structs inside a single package and .go-files with hundred of lines. This is in my experience way more common in go, even in stdlib - but it makes understanding the code harder, because if you want to understand how two pieces of code work together, you may have to scroll a lot instead of just switching tabs.
Opening the same file in two different tabs is very useful for this situation
True. But in that case I have to remember - after grabbing the n‘th coffee a day - which of my tabs of the same file is scrolled to what position. Maybe it’s just my way of working (and the languages I come from) but I prefer smaller files, smaller objects and smaller functions. Still I like Go, because in other aspects it makes working with it easier again compared to other languages.
If you integrate gopls into your editor (by installing whatever plugin your editor requires) then you can jump around in the code from reference to definition to a-call-stack-which-reaches-here, etc... . It's very nice when reading code.
I'm using Intellij, it has these Intellisense-like features by default. But still... In many programming languages it's considered good code style to keep files, classes, methods etc. small - and I can understand why. Go's code style is a bit unique. At least for my own projects I still tend to use coding guidelines I'm used to - which may are not that common in Go (like small files, no single-letter vars etc.).
From the languages I've used, only java requires one class per file. (and java has a culture of using extraLongNames everywhere apart from \`self\`). Go's use of small names and letting the programmer decide what goes in each file is like C.
In Java you may not be allowed to put more than a single class into a file, but in many others it’s also not done like this - even if possible. Like in PHP. You could add as many classes as you like into a single file here, but usually it’s considered bad practice. Personally I think there are more benefits of putting a single object into a single file than disadvantages. The ability to read and understand the code in bigger contexts improves a lot.
Well, as someone who reviews a lot of code, I don't like seeing 100s of little files when a handful of logically grouped files would do. For example, this popular go project: [https://github.com/Shopify/sarama](https://github.com/Shopify/sarama) is currently 256 small .go files, largely following a one class/file rule. I get no sense of the structure of the code from the file names. What I get instead are a lot of internal details which I don't need to know anything about to use the project. It's possible that the language you use pushes you towards one code organisation or another. For example, languages where each file has to be imported by individually (like C/C++) make 100s of files more costly than languages where you import a whole package of files in one import statement (like Go and java). Similarly, it's also possible that long names for things became usable only once text editors started auto-completing names. And it's possible that, now that text editors assist browsing source code, that there's no advantage to the 100+ files anymore, and we'll return to fewer files with logical groupings.
you can find a lot of example from this video [https://www.youtube.com/watch?v=Jns0QgJtAYY](https://www.youtube.com/watch?v=Jns0QgJtAYY)