Go is a language that (like C, C++, Lisp, and many others) compiles to a native binary on every platform it supports. This is important for graphical applications as it's the best way to create the most responsive and smoothest user interfaces on mainstream computer hardware. At the time of writing, the platforms that Go runs on includes Windows, macOS, Linux, Solaris, and other popular Unix-based operating systems (which is essentially all desktop personal computers). What stands out about Go compared to other modern languages is that its source code will compile, without any alterations or special adaptation, to native code on every platform that it supports. The language also comprises a large library of APIs that fully support every one of its supported operating systems. This is a huge advantage for developers who want to write an efficient application for multiple operating systems without maintaining slightly different versions for each platform. Go is also a typed language, which means that every variable, constant, function parameter, and return type must have a single, defined type. Unlike some older typed languages, Go is often able to infer a type, which helps avoid the duplication of information in the source code. These features help to create a language that's great for development—so let's look at some real code and how this is built and run. We'll work with a simple hello world example, which we will write into a file named main.go:
package main
import "fmt"
func main() {
fmt.Println("Hello World!")
}
This example shows the most basic Go program. The first line indicates the package name (here, main means that the file describes an executable command). Then, we have the import block where you reference any standard library packages or external code. Finally, there is a main() method, which is the start of any Go program—and this method simply prints Hello World! to the command line using the fmt package. This method doesn't mention a return type (which would be placed after main())—that means there is no return type, such as void in C or Java programs. We run this application using the go run main.go command, as follows:

Alongside each Go file will usually be a test file that runs unit tests against the main code. Let's demonstrate that with another trivial example. Enter the following code into main_test.go:
package main
import "testing"
func TestLogic(t *testing.T) {
if true == false {
t.Error("It's illogical")
}
}
Before we run this code, you should notice two important differences compared to a regular Go file. First, the import list includes "testing"—this is required for writing any test method. Second, the method name starts with Test this time, and includes a single parameter of the *testing.T type. Any method that conforms to those conditions and is in a file that has a name ending in _test.go will be considered a unit test. Now let's run the tests using the built-in test runner:

In this command, the -v parameter requests verbose output, which is seen as the tests run, and the resulting command-line-arguments indicates that the tests were run on the files specified in our parameter list, rather than a full package. Alternatively, typing go test would output less information and would run all the tests in the current package.
In addition to these basic commands, Go comes with many tools that help developers to write and maintain high-quality code. The three that are most commonly used are as follows:
- gofmt: This ensures that source code is formatted according to the Go specification, and can rewrite your files if requested (by passing -w).
- godoc: This runs a local documentation server to check how your API will look to other developers.
- go vet: This examines the code for common programming mistakes that a compiler won't detect.
You may have noticed that these commands simply run without needing to compile – but how can that be, if Go is a compiled language? That is because the run command is actually a shortcut to build the application and then run it. This makes running the latest version of an application much quicker than the usual approach of compiling and then running, without losing any of the benefits of being a native binary. In this mode, the built application is discarded when the run finishes. If you want to build and then run many times, you can use the build command, as shown here:

As you can see, the compiler has created an executable file that has the same name as the file we entered the code into. This file is the native application built from our source code and it can be run like any other application. Note that this is a native application and so it's not portable the way that a Java application is. It will run on the computer we built it on and others like it, but an application built on a Windows computer will not run on macOS directly. The source code is compatible with both platforms, but the binary application is not.
It should be noted at this point that the Go language also provides garbage collection, which contributes to the ease of development. This means that when objects we created are no longer needed, the system will ensure the memory they occupy is freed up. Compared to C and other (older) compiled languages where this isn't provided, we have less code to write, and a much lower risk of our application leaking memory. Now that we know the language, let's explore the compiler features that support the cross-platform approach and see how to build these examples for different operating systems.