Variables, types, and the zero-value trick
If you are coming from JavaScript, the first thing that will jump out about Go is that variables have types and the compiler will yell at you. The second thing is that nothing is ever undefined. Both of these are gifts. This lesson covers how Go declares variables, the basic types, and the zero-value rule that quietly removes a whole category of 3 AM bugs.
Two ways to declare, one you will use 95% of the time
Go has var and :=. They do almost the same thing.
var count int = 10
var name = "Razorpay" // type inferred as string
city := "Bengaluru" // short form, only inside functionsThe := short form is what you will reach for inside functions. It declares and assigns in one line. Use var at the package level, or when you want the zero value without assigning.
var price float64 // price is 0.0, ready to use
var active bool // active is false
var users []string // users is nil, but you can still append to itSenior rule: prefer
:=inside functions for readability, but usevar x Twhen you specifically want the zero value as your starting point.
The basic types you will actually use
Go has many numeric types. In real code, you reach for a handful.
int: the default integer. 64-bit on modern machines. Use this for counts, indices, IDs that fit.int64: when you specifically need 64 bits, like UPI transaction amounts in paise or Unix nanoseconds.float64: the default float. Use for prices, ratios, anything fractional. Never usefloat32unless you have a reason.string: immutable bytes, usually UTF-8.len(s)returns bytes, not characters.bool:trueorfalse. No truthy nonsense.byteandrune: aliases foruint8andint32.bytefor raw bytes,runefor a Unicode code point (one Devanagari character).
amount := 49900 // int, paise
upiRef := "ZHJ8K2M" // string
verified := true // bool
gst := 18.0 // float64You will spend most of your career in these five. The other numeric types exist for when the wire protocol says so.
The zero-value trick
Every type in Go has a zero value. If you declare a variable without assigning to it, you get that zero value. Not undefined, not a crash, a real usable value.
int,float64→0string→""bool→false- pointers, slices, maps, channels, functions, interfaces →
nil struct→ every field set to its own zero value
This sounds boring until you realise what it removes. There is no "uninitialised garbage" in Go. There is no if (x !== undefined && x !== null) dance at the top of every function. The variable exists. It has a value. You can use it.
var orders []string
orders = append(orders, "order-001") // works, even though orders was nilSenior rule: Go's zero values are not "default values you might forget to set". They are part of the type contract. Designing your structs so the zero value is useful is idiomatic Go.
Constants and iota
Constants are compile-time values. Declare with const. The iota keyword inside a const block auto-increments, perfect for enums.
const (
StatusPending = iota // 0
StatusPaid // 1
StatusRefunded // 2
StatusFailed // 3
)No magic numbers in your handlers. The compiler now knows these are a related set, and you can attach a method to a typed iota for stringification later.
When the compiler saves you
Try to assign a string to an int variable and the compiler refuses, with a clear "cannot use string as int" message. You will hit this on day one and roll your eyes. By month three, you will realise the compiler caught a bug that would have been a 2 AM Slack ping in Node. The same goes for shadowing, unused variables, and unused imports. Go treats every one of these as a build break, not a warning, which keeps real codebases honest.
Quick reference
- Zero value
- The default value every Go variable gets when declared without assignment. Safe to use, never undefined.
- :=
- Short variable declaration. Declares and assigns. Only legal inside functions.
- var
- Long-form declaration. Works at package level. Use when you want the zero value explicitly.
- iota
- Auto-incrementing identifier inside a const block. Used for enum-like sets.
- rune
- Alias for int32. Represents a single Unicode code point.
- Type inference
- The compiler figuring out the type from the right-hand side. Lets you skip type annotations on locals.
Next lesson, functions and the err pattern. That is where Go starts looking really different.
Watching quietly. Tap me if you want a tip.
Go cannot run natively in a browser. Run copies your code and opens go.dev/play ; paste and click Run there.
Try this (0 of 2 done)
- 1
What is the output? (Hint: zero values for int, string, bool.)
hint
int -> 0, string -> "" (empty), bool -> false
show answer
package main import "fmt" func main() { var n int var s string var b bool fmt.Println(n, s, b) } - 2
Predict: what does `const Pi = 3.14; fmt.Println(Pi * 2)` print?
show answer
package main import "fmt" func main() { const Pi = 3.14 fmt.Println(Pi * 2) }