Skip to main content

Go Getting Started - Setup & Hello World

For developers with .NET (C#) experience, this guide covers installing Go, the go command, editor setup, and writing your first program.

1. Installing Go​

Official installer​

Download an installer or archive for your OS from go.dev/dl.

# Linux (extracting the archive; adjust the version as needed)
sudo rm -rf /usr/local/go
sudo tar -C /usr/local -xzf go1.xx.x.linux-amd64.tar.gz
export PATH=$PATH:/usr/local/go/bin

# macOS (Homebrew)
brew install go

# Windows (winget)
winget install GoLang.Go

Verify the installation:

go version
go env GOPATH GOROOT GOOS GOARCH

Version management​

The equivalent of .NET's global.json is the go / toolchain directives in go.mod. Since Go 1.21, if go.mod requires a newer version than the one installed, Go automatically downloads and uses the required toolchain (controlled by the GOTOOLCHAIN environment variable).

module example.com/hello

go 1.24

To switch between multiple versions manually, use the official golang.org/dl or a version manager such as mise or asdf.

2. .NET Mapping​

.NET (C#)Go
dotnet new consolego mod init <module> + create main.go
dotnet rungo run .
dotnet buildgo build
dotnet publishgo build / go install (output is a single binary)
dotnet add packagego get <module>
dotnet restorego mod download (usually automatic)
dotnet formatgofmt / go fmt ./...
Roslyn analyzersgo vet ./... / golangci-lint
dotnet testgo test ./...
global.jsongo / toolchain in go.mod
Visual Studio / Rider / C# Dev KitVS Code + gopls / GoLand

3. Key go Commands​

CommandPurpose
go mod init <module>Create go.mod and initialize a module
go run .Compile the current package and run it immediately (output goes to a temp directory)
go buildCompile and produce an executable
go installBuild and place the result in $GOPATH/bin (or GOBIN). Also used to install CLI tools
go fmt ./...Format code with the standard formatter (gofmt)
go vet ./...Detect suspicious code through static analysis
go test ./...Run tests
go mod tidyRemove unused dependencies and add missing ones
go doc <pkg>Read documentation in the terminal

./... is a wildcard meaning "all packages under the current directory."

4. Editor Setup​

VS Code​

  1. Install the Go extension (Go Team at Google)
  2. Run Go: Install/Update Tools from the command palette to install gopls (language server), dlv (debugger), and others

Recommended settings (settings.json):

{
"go.formatTool": "gofmt",
"editor.formatOnSave": true,
"[go]": {
"editor.codeActionsOnSave": {
"source.organizeImports": "explicit"
}
}
}

Formatting and import organization run automatically on save. In Go, even the ordering of import statements is decided by tooling.

GoLand​

A commercial IDE from JetBrains with a feel close to Rider. Go SDK detection, debugger, and refactoring work right after installation.

5. Hello World​

Create the project​

mkdir hello && cd hello
go mod init example.com/hello

This generates go.mod. It is similar to a .csproj, but you do not list files; all .go files in the directory are included automatically.

main.go​

package main

import "fmt"

func main() {
fmt.Println("Hello, Go!")
}

Run and build​

go run . # run
go build -o hello . # produce a binary (hello.exe on Windows)
./hello # run the generated binary

Comparison with C#​

// Program.cs (top-level statements)
Console.WriteLine("Hello, C#!");
// main.go
package main

import "fmt"

func main() {
fmt.Println("Hello, Go!")
}
  • Go has no top-level statements, so package main and func main() are required.
  • An executable program is a package main that contains a main function. Any other package is a library.
  • Importing a package without using it is a compile error.

A slightly more practical example​

This example takes an argument and handles errors.

package main

import (
"fmt"
"os"
"strconv"
)

func main() {
if len(os.Args) < 2 {
fmt.Fprintln(os.Stderr, "usage: hello <count>")
os.Exit(1)
}

n, err := strconv.Atoi(os.Args[1])
if err != nil {
fmt.Fprintf(os.Stderr, "invalid count: %v\n", err)
os.Exit(1)
}

for i := range n {
fmt.Printf("Hello #%d\n", i+1)
}
}
go run . 3

for i := range n (range over an integer) is available in Go 1.22 and later.

Using an external package​

go get github.com/google/uuid
package main

import (
"fmt"

"github.com/google/uuid"
)

func main() {
fmt.Println(uuid.NewString())
}

go get updates go.mod and records checksums in go.sum. Commit both go.mod and go.sum. go.sum plays a role similar to packages.lock.json.

6. Common Pitfalls for C# Developers​

  1. go run works per package, not per file: go run main.go works, but once the code is split into several files, use go run ..
  2. You do not need to think about GOPATH: It used to be required to place source under GOPATH, but with Go Modules you can create a project in any directory. GOPATH is now mainly used for the downloaded module cache ($GOPATH/pkg/mod) and install location ($GOPATH/bin).
  3. Installed tools are not found: Commands installed with go install land in $(go env GOPATH)/bin. Add that directory to your PATH.
  4. Do not debate formatting: Indent with tabs and put opening braces at the end of the line. The output of gofmt is the standard, and there are no settings.
  5. Brace position is part of the grammar: Putting { on a new line after func main() is a compile error (because of automatic semicolon insertion).
  6. Unused variables and imports are errors: Explicitly discard a variable you do not need yet with _ = x or _.
  7. Only package main is executable: Running go build on a library does not produce a binary. It only type-checks.
  8. No bin/ and obj/ clutter: go build writes the executable to the current directory (changeable with -o). Add it to .gitignore.

7. Summary​

  • Installation is done with the official installer alone, and go / toolchain in go.mod pins the version (Go 1.21+ automatically fetches the required toolchain).
  • go mod init → go run . → go build is the basic flow, equivalent to dotnet new → dotnet run → dotnet publish.
  • VS Code + gopls provides format-on-save, import organization, completion, and debugging.
  • Next, move on to Modules and Packages and Basic Syntax.

References​