Frontendmasters course on Go basics — Source.
- Three main pillars of Go philosophy: ease of coding, efficient compilation, efficient execution.l
main
function is an entry point for a Go program.- Go programs consist of packages. In most cases, one can thing of a package like a folder with source code files.
- A package actually ends up compiled as a single long file, even if you had broken up the package into multiple files.
- This explains why variables and functions are available across files within a package.
- Package name has no relationwith the folder name containing the package (i.e. they can be different).
- It's not advised to have nested packages in Go. It is possible to have a private sub-package though.
- In Go, module mostly stands for an application.
- Variables of different types have different "default" values: emtpty string, 0, false,
nil
for pointers. - Q: there's
print
function available by default, why usefmt
package? A:fmt
tries to be a robust way to provide values to standard output, whileprint
might not work on every OS or platform. - Visibility is simple in Go — things starting with uppercase are visible, while lowercase properties are private.
- In Go it's possible to convert types, i.e. an int can be converted to
float64
—var i = 10; float64(i)
. - Arrays are explicit about their nature in Go. Since arrays have fixed size, it is clear from the type, i.e.
[3]string
. - In Go, every source file can have an
init
function — documentation.- Usecases: complex initialisation that cannot be expressed as declarations or checking the current state of the program to possibly reset state/recover in any way.
- In Go, nothing is an object. Thus executing things like
myArray.length
doesn't make sense in Go (here we'd uselen(myArray)
). - Operating with slices (a.k.a dynamic arrays in Go) looks a lot like working with immutable arrays in JavaScript.
- Arguments are always passed by value in Go functions. Thus, when we need a side effect, we pass a pointer.
- Formatting can be quite simple in Go — there's a shortcut of
%v
that we can use as a placeholder for a value in a function likefmt.Sprintf
. - I didn't know this, but it is possible to have a pointer to a pointer in Go. I assume the same should be possible in C too, although I've never seen a pointer to a pointer yet (for good reasons perhaps).
- Functions can
panic
. This is complete halt of execution.- Side note — at first I was wondering if function signature can express if a panic is possible, but on the second thought, knowing that in advance won't help, as execution will be stopped before we can recover.
defer
is a useful keyword in Go. It helps to defer execution of a line of code until the end of the block scope of a function. Can be nice for closing database connections, etc.- Also, defers are executed before
panic
shuts down the program.
- Also, defers are executed before
- In golang, there's only
for
loop available. However, it has quite a flexible structure (can work with conditional expression for instance). - You can create a variable, that will only be accessible within the scope of the
if
block, quite handy. - Go has sweet switch statement, which allows to specify a dedicated condition for every case (something I miss in JS's switch).
- In Go, you are one keystroke away from reading source files of the dependencies you use (follow definition from your text editor or IDE). That's a relief after walls of TS declarations.
- In Go, you can introduce a type alias for one of the standard types. You can define a method for a type alias, which is not possible for the standard types.
- It is not mandatory to pass all values when creating a struct in Go.
- This initially made me think "oh and how do I ensure that a certain property is populated?". The answer seems to be constuctor functions (referred to as "factory functions" in the course).
- In Go there's no inheritance, but we have type embeddings instead. One type can incorporate another in it's definition, and both will be "merged".`
- When embedding a type, methods defined on the embedded type also become available.
- If you define a
String
method on a struct, you can then pass it tofmt.Printf
. - If you add a comment to a type, it becomes visible like "docs" to the type (i.e. when doing Shift+K).
- In Go, interfaces are used to define a shape that types must conform to (i.e. to be able to pass a certain type to a function).
- You don't need to explicitly specify that a certain type implements a certain interface. This is called "implicit implementation".
- Note to self — while goroutines are easy, I should at some point properly learn multithreading, parallelism, green threads and other key terms.
- Goroutines are not guaranteed to get executed. If the main goroutine ends, that's it.
- If your function is supposed to return a value of particular type, say (Rate, error), you cannot just use
nil
as the value there. The trick in Go to work around that is to return a pointer to the value - (*Rate, error). Pointers can be nil, so it's ok.- This is why most of the times when an API has to return a structure, it returns a pointer to a structure instead.
- Dot operator also serves as a shortcut to dereference a pointer.
- Since JSON responses might not exactly map to the types of our applications, it is common to create a ResponseType specifically for a third party API, which can later be "converted" to a type that we initially had in mind.
- Structs can have those comments declared, and for example json package relies on those comments to match json properties to properties of the ResponseType. To be clear, this is done as ResponseType properties are starting with Uppercase letters to be public, and JSON is unlikely to have uppercase letters in properties.
- I was amazed how even async operations looks like synchronous operations in Go. It turns out, those operations are in fact synchronous — there's a chance that if we look into the sources of functions like http.Get, there will be a for loop waiting for results.
- There's a new concept of test "Fuzzing", I should probably look it up later.
- Something I ran into: if I just execute
go test
in root, it will report there are no test files. It turns out, that one should test recursively withgo test -v ./...
command. - Random reflection — I compare my experience of learning Go with my experience of learning OCaml. And I feel tenfold more confident following a video course, as you have your questions along the way, and if the instructor is good, they will add extra context that will help to answer your questions.