Each place where a declaration occurs is called block. Variables, constants, types and functions declared outside of any functions are placed in the package block.
A shadowing variable is a variable that has the same name as a variable in a containing block.
Universe Block
Go has 25 keywords.They cannot be used as identifiers (like variable names, function names, etc.).
break default func interface selectcase defer go map structchan else goto package switchconst fallthrough if range typecontinue for import return var
Predeclared identifiers
Predeclared identifiers are built-in names provided by the Go language that you can use in your programs. Unlike keywords, they can be shadowed (redeclared), but it’s usually not recommended.
Go considers these predeclared identifiers and defines them in the universe block, which is the block that contains all other blocks.
// Typesbool byte complex64 complex128 error float32 float64int int8 int16 int32 int64 rune stringuint uint8 uint16 uint32 uint64 uintptr// Constantstrue false iota nil// Functionsappend cap close complex copy delete imag lenmake new panic print println real recover
func main() { if n := rand.Intn(10); n == 0 { fmt.Println("That's too low") } else if n > 5 { fmt.Println("That's too big:", n) } else { fmt.Println("That's a good number:", n) } fmt.Println(n) // 🔴 Out of Scope. n in if scope.}
func main() { n := rand.Intn(10) if n == 0 { fmt.Println("That's too low") } else if n > 5 { fmt.Println("That's too big:", n) } else { fmt.Println("That's a good number:", n) } fmt.Println(n) // This works. }
For
1. Complete, C-style for
for i :=; i < 10; i++ { fmt.Println(i)}i := 0for ; i < 10; i++ {fmt.Println(i)}
2. Condition Only for
i := 1for i < 100 { ///}
3. Infinite Loop
for { fmt.Println("Hello")}
Break and Continue
Go does not have while of do- while loop. we can use following pattern to do-while loop.
for { if !condition { break }}// 😲 NOTE: that the condition has a leading ! to negate the condition from the Java code. The Go code is specifying how to exit the loop,while the Java code specifies how to stay in it
Go encourages short if statement bodies, as left-aligned as possible. Nested code is more difficult to follow.
4. For-Range
for-range loop only to iterate over the built in compound types and use-defined types that are based on them. compound types are types that are made by combining other types—they are not basic primitives like int or bool.
Type
Description
For-range Returns
Array
Fixed-size sequence of elements
index, value
Slice
Dynamic-size array-like structure
index, value
Map
Key-value pair collection
key, value
String
Sequence of bytes (interpreted as UTF-8)
index, rune (index is byte index, rune is Unicode code point)
Channel
Concurrency-safe communication pipe
value only (until channel is closed)
Anytime you are in a situation where a value is returned, but you want to ignore it, use an underscore to hide the value., Go allows you to just leave off the second variable.
uniqueNames := map[string]bool{"Fred": true, "Raul": true, "Wilma": true}for k := range uniqueNames { fmt.Println(k)}
for-range over a map produces a different order each time, even with the same data. This is security improvement( > 1.12 ).
This behavior is intentional, to:
Avoid reliance on iteration order.
Protect against Hash DoS attacks.
Go introduces randomness in the internal map hashing at runtime, not compile time.
package mainimport "fmt"func main() { for i := 0; i < 3; i++ { for k := range map[string]int{"a": 1, "b": 2, "c": 3} { fmt.Print(k, " ") } fmt.Println() }}// Outputs// b a c // c b a // a c b
Exception
Functions like fmt.Println(m) or fmt.Printf("%v", m)sort the keys so the output is deterministic and readable.
m := map[string]int{"c": 3, "a": 1, "b": 2}fmt.Println(m) // Output: map[a:1 b:2 c:3] ← sorted by key
for-range over a String in Go
When you use a for-range loop on a string, Go iterates over runes, not bytes.
A rune is a Unicode code point (an int32), while strings are stored as UTF-8 encoded bytes.
for-range value is a copy
evenVals := []int{2, 4, 6, 8, 10, 12}for _, v := range evenVals { v *= 2 // modifies copy only, not original slice}fmt.Println(evenVals)
Outer:for i := 1; i <= 3; i++ { for j := 1; j <= 3; j++ { if j == 2 { continue Outer } fmt.Println(i, j) }}
Switch
In Go, switch statements do not fall through by default, unlike in C, Java, or JavaScript.
x := 2switch x {case 1: fmt.Println("One")case 2: fmt.Println("Two")case 3: fmt.Println("Three")}// Output// Two
Go provides the fallthrough keyword — but it must be the last statement in the case.
Go does include a fallthrough keyword, which lets one case continue on to the next one. Please think twice before implementing an algorithm that uses it. If you find yourself needing to use fallthrough, try to restructure your logic to remove the dependencies between cases.
x := 1switch x {case 1: fmt.Println("One") fallthroughcase 2: fmt.Println("Two")}// Output// One// Two
In Go, an empty case means nothing happens.
Blank Switches
Just as Go allows you to leave out parts from a for statement’s declaration, you can write a switch statement that doesn’t specify the value that you’re comparing against.
words := []string{"hi", "salutations", "hello"}for _, word := range words { switch wordLen := len(word); { case wordLen < 5: fmt.Println(word, "is a short word!") case wordLen > 10: fmt.Println(word, "is a long word!") default: fmt.Println(word, "is exactly the right length.") }}
Use a blank switch when you have multiple related boolean cases, like input validation, status checks, or condition-based formatting.
goto
You should try very hard to avoid using goto. But in the rare situations where it makes your code more readable, it is an option.