I've found a lot of interesting features and ideas in Go (golang). By exploring these, I've got several things to try out in my primary language (which is currently C#).
If you're curious about Go, I've put together a tour of the language targeted at the C# developer. By building an application that makes concurrent service calls, we can see some of the similarities and differences between C# and Go.
Watch it on YouTube: A Tour of Go (golang) for the C# Developer
There's also a repo with all of the code: https://github.com/jeremybytes/video-go-for-csharp-dev
Here are a few of the things I find interesting about Go:
Go syntax is C-like, but it has some strong opinions. For example, opening curly braces must always go on the same line as the function (or "if", or other block statement). In addition, the curly braces are never optional for an "if" statement, regardless of how many lines are part of the body.
No Unused Variables
Go does not allow for unused variables. If you declare a variable and do no use it, you get a compiler error. I like this idea since it gets rid of code that isn't used. This also encourages the use of the "blank identifier" (an underscore) which acts as a discard.
Concurrency is baked right into the Go language -- in fact, they are called "goroutines" and you use "go" to start one. Channels can be used to communicate between a goroutine and other functions. Seeing how they work makes the idea of Channels in C# (added in .NET Core 3.0) a bit more interesting to explore.
Go has a "defer" statement. For example, "defer channel.Close()" will call the "Close()" method at the end of the function (however it exits). This is similar to a "finally" in C#, but it can be used anywhere in a function or method.
Go encourages the the use of "error" instead of exception (which is called "panic" in Go). An error is really just a message. A common pattern is for a function to return a data item plus an error. If the error is populated, then something went wrong. The idea is that we treat errors as messages to be handled in our own code rather than something to be handled by the language or framework. (And "panic" does exist if we have a truly panic-inducing circumstance.)
Multiple Return Values
As mentioned above, it's common for a function to return a data item plus an error. Go supports multiple return values. So we can return multiple values without dealing with explicit tuples.
Interfaces in Go are explicitly declared but implicitly implemented. Meaning, if we have an interface that declares a "String()" method, a type can implement that the interface by simply providing a "String()" method. It does not need to specifically say it implements the interface, it just needs to provide the members. This encourages a different way of using defining and using interfaces. I wrote a bit about my initial experiences here: Go and Interfaces.
Check Out the Video
In building a small application (about 100 lines), the video looks at all of these features, plus a few more. Be sure to check it out: