Hello, Go
In PHP, the smallest program is one line. Open a file, write <?php echo "Hello";, run it, done. PHP starts at the top of the file and works its way down, running whatever it finds.
Go doesn't run "whatever it finds". There's no code at the top level of a Go file at all: no loose statements, no echo floating around. Instead, every Go program has exactly one front door.
The front door: package main and func main
Here's the Go version of hello world:
package main import "fmt" func main() { fmt.Println("Hello, Go!") }
Three things are going on:
package main: every Go file starts by saying which package it belongs to. A package is simply all the.gofiles in one directory, so a program can be split across as many files as you like.mainis special: it means "this package builds into a program", not a library.import "fmt": Go has no autoloader. If you use a package, you import it, by name, at the top of the file.fmt(say "fumpt" if you want to sound like you've been doing this for years) is the formatting and printing package.func main(): the entry point. When the program starts, Go callsmain. Whenmainreturns, the program ends. No arguments, no return value.
fmt.Println is roughly echo, except it adds a newline for you, so no more "\n" or PHP_EOL at the end of every line. Pass it several values and it puts a space between each one, which echo never does. The Interchange tab has both side by side.
Laravel corner
Laravel's real front door is public/index.php: it boots the autoloader, builds the container and hands the request to the kernel. In Go, func main is all of that at once. Whatever your app needs, main builds it, explicitly, in plain code you can read top to bottom. No service providers, no magic. You'll grow to love it, eventually.
Functions that take arguments
main takes nothing and returns nothing, but most functions you write will do both. Here's one you might write for a departure board, next to its PHP twin:
func announce(dest string, platform string) string { return dest + " from platform " + platform }
function announce(string $dest, string $platform): string { return "{$dest} from platform {$platform}"; }
The pieces are all there, just shuffled: the type goes after the name, there's no $, and the return type sits after the closing bracket with no colon. When neighbouring parameters share a type you can group them, so func announce(dest, platform string) string means exactly the same thing. You'll see that shorthand everywhere. (Platform is a string because, as any commuter knows, platform 9b exists.)
The compiler has opinions
Go is compiled, and the compiler is strict in ways PHP never was. Three of them catch every PHP dev in their first week.
Unused imports are errors. Import os and don't use it, and the build fails with "os" imported and not used. Same for unused local variables. It's annoying for about a day, and then you notice your files no longer collect junk.
Single quotes are for single characters. In PHP, 'Hello' and "Hello" are both strings. In Go, double quotes (or backticks) make strings, and single quotes make a rune, which is one character. fmt.Println('Hello') won't compile: more than one character in rune literal.
Mind the gap
Your PSR-12 braces will break the build. PSR-12 puts a function's opening brace on its own line. In Go that's a syntax error, not a style choice: Go inserts semicolons at line ends for you, so func main() followed by a newline is treated as a complete (and broken) statement. The opening brace always goes on the same line. The good news: gofmt formats everything else for you, so this is the last brace argument you'll ever have.
Running it
On your machine, a Go project needs a go.mod file first, the way a PHP project needs a composer.json. go mod init example.com/hello creates one (lesson 0.4 explains what that name is for). After that, go run . compiles and runs the program in the current directory. (Lesson 0.3 covers the toolchain properly.)
In this course, the Run button does the same thing in a sandbox, and Submit runs the hidden tests against your code. Stuck? Hints unlock one at a time, and lesson 0.6 explains exactly what happens behind Submit.
Recap
- A Go program starts at
func maininpackage main. There's no top-level code. - Imports are explicit, and unused imports (or variables) are compile errors.
fmt.Printlnprints its arguments separated by spaces, with a newline at the end. Strings use double quotes, never single.- Opening braces go on the same line. Always.