- Multiple imports should be in curly braces.
- Tab indentation is must for proper formatting and readability and is enforced in golang.
- Multiple import statements can be written.
- Exported names should start with a capital letter.
- A function can take zero or more arguments.
- When two or more consecutive named function parameters share a type, you can omit the type from all but the last.
- A function can return any number of results.
- Named return values --> A return statement without arguments returns the named return values. This is known as a "naked" return. Naked return statements should be used only in short functions, They can harm readability in longer functions.
- The var statement declares the variable with type in last or a list of variables with tyoe in last if all are of same type.
- A var statemenet can be at global and function level.
- Var declaration can include iitalizers one per variable.
- Using Var, type can be omitted and varible will take initializer type.
- Short variable declartions -->Inside a function, the := short assignment statement can be used in place of a var declaration with implicit type. Outside a function, every statement begins with a keyword (var, func, and so on) and so the := construct is not available.
-
bool
-
string
-
int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64 uintptr
-
byte // alias for uint8
-
rune // alias for int32 // represents a Unicode code point
-
float32 float64
-
complex64 complex128
-
The int, uint, and uintptr types are usually 32 bits wide on 32-bit systems and 64 bits wide on 64-bit systems. When you need an integer value you should use int unless you have a specific reason to use a sized or unsigned integer type.
| Type | Size/Range | Default | When to Use |
|---|---|---|---|
bool |
true/false | false | Flags, conditions |
int |
32/64-bit | 0 | General integer arithmetic |
int32/int64 |
Fixed-width | 0 | File formats, DB IDs |
uint8 (byte) |
0–255 | 0 | Raw binary, byte data |
rune (int32) |
Unicode | 0 | Text, characters |
float32 |
6–7 digits | 0.0 | Memory-sensitive calculations |
float64 |
15–16 digits | 0.0 | Default for real numbers |
complex64/128 |
Complex nums | 0+0i | Scientific/maths |
string |
UTF-8 bytes | "" | Text data |
*T (pointers) |
address | nil | Sharing/mutating data |
| Type | Size (bits) | Range / Values | Default |
|---|---|---|---|
| bool | 1 (logical) | true or false |
false |
| int8 | 8 | -128 to 127 | 0 |
| int16 | 16 | -32,768 to 32,767 | 0 |
| int32 | 32 | -2,147,483,648 to 2,147,483,647 | 0 |
| int64 | 64 | -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 | 0 |
| int | 32/64 | Arch dependent (same as int32 or int64) | 0 |
uint8 (byte) |
8 | 0 to 255 | 0 |
| uint16 | 16 | 0 to 65,535 | 0 |
| uint32 | 32 | 0 to 4,294,967,295 | 0 |
| uint64 | 64 | 0 to 18,446,744,073,709,551,615 | 0 |
| uint | 32/64 | Arch dependent | 0 |
rune (int32) |
32 | Unicode code points: 0 to 1,114,111 (U+10FFFF) |
0 |
| float32 | 32 | ~±1.18e−38 to ±3.4e38 (6–7 digits precision) | 0.0 |
| float64 | 64 | ~±2.23e−308 to ±1.8e308 (15–16 digits precision) | 0.0 |
| complex64 | 64 | real+imag parts as float32 | 0+0i |
| complex128 | 128 | real+imag parts as float64 | 0+0i |
| string | varies | sequence of bytes (UTF-8) | "" |
pointer (*T) |
Arch size | memory address / nil |
nil |
- int and uint depend on your machine (32-bit vs 64-bit).
- rune is for Unicode code points (not the same as character length).
- byte is just an alias for uint8.
- Strings are immutable, default is empty string.
Go has the strconv package for converting to/from strings.
This document shows examples of string conversions in Go.
package main
import (
"fmt"
"strconv"
)
func main() {
// String → Integer
s := "123"
i, err := strconv.Atoi(s)
if err != nil {
fmt.Println("Error:", err)
}
fmt.Println("String to Int:", i)
// Integer → String
n := 456
str := strconv.Itoa(n)
fmt.Println("Int to String:", str)}
// integer to string
i := 123
s := strconv.Itoa(i)
fmt.Println(s) // "123"
// string to float
f, err := strconv.ParseFloat("3.14", 64)
fmt.Println(f) // 3.14
// float to string
f := 3.14
s := strconv.FormatFloat(f, 'f', 2, 64) // 'f'=decimal, 2=precision
fmt.Println(s) // "3.14"
// String <-> Byte slice
str := "hello"
b := []byte(str) // string → []byte
fmt.Println(b) // [104 101 108 108 111]
newStr := string(b) // []byte → string
fmt.Println(newStr) // "hello"
// String <-> Rune slices
str := "हेलो" // Hindi "Hello"
r := []rune(str) // string → []rune
fmt.Println(r) // [2361 2375 2354 2379]
fmt.Println(string(r)) // "हेलो"
// String <-> Boolean
s := strconv.FormatBool(true) // "true"
b, _ := strconv.ParseBool("true")
fmt.Println(b) // true
}-
A string in Go is a read-only slice of bytes ([]byte).
-
But since Go strings are UTF-8 encoded, one character (Unicode codepoint) can take 1–4 bytes.
This is why we need both []byte and []rune.
- Type: uint8 (0–255).
- Represents raw binary data or ASCII characters.
- When you convert a string to []byte, you get its UTF-8 encoded representation
s := "Go语言"
b := []byte(s)
fmt.Println(b)
// [71 111 232 175 173 232 175 180] (UTF-8 bytes)
s := "Go语言"
r := []rune(s)
fmt.Println(r)
// [71 111 35821 35328] (Unicode code points)
for _, ch := range r {
fmt.Printf("%c ", ch)
}
// Output: G o 语 言
Use [ ]byte when:
-
Reading/writing files, sockets, binary protocols, hashing, compression.
-
You care about storage & transmission.
Use [ ]rune when:
-
Processing or indexing human-readable text.
-
You care about characters, not bytes.
- Constants are declared like variables, but with the const keyword.
- Constants can be character, string, boolean, or numeric values.
- Note: Constants cannot be declared using the := syntax.
Go has only one looping construct, the for loop. The basic for loop has three components separated by semicolons:
- init statement: executed before the first iteration
- condition expression: evaluated before every iteration
- post statement: executed at the end of every iteration
The init statement will often be a short variable declaration, and the variables declared there are visible only in the scope of the for statement.
Note: Unlike other languages like C, Java, or JavaScript there are no parentheses surrounding the three components of the for statement and the braces { } are always required.
Init and post statement are optional. For is Go's "while" At that point you can drop the semicolons: C's while is spelled for in Go.
Note:
- If you omit the loop condition it loop foreever,so infinite loop is compactaly expressed.
- No parentheses around the condition.
- Curly braces are must. variable can be declared inside if statement and its scope is inside if statement only.
if v := math.Sqrt(16); v == 4 {
fmt.Println("Perfect square")
}
if x > 10 {
fmt.Println("x is greater than 10")
} else if x == 10 {
fmt.Println("x is exactly 10")
} else {
fmt.Println("x is less than 10")
}
Go’s switch is more powerful than C/Java.
x := 2
switch x {
case 1:
fmt.Println("One")
case 2:
fmt.Println("Two")
case 3:
fmt.Println("Three")
default:
fmt.Println("Other number")
}
Note:
- No need for break like C/Java, Go automatically breaks after matching case.
- If no case matches, default runs.
main() {
day := "Saturday"
switch day {
case "Saturday", "Sunday":
fmt.Println("Weekend")
default:
fmt.Println("Weekday")
A single case can match multiple values. You can declare variables inside the switch. (The scope is only inside that switch block).
In Go, fallthrough is a statement you can put at the end of a case block. “After executing this case, continue execution at the next case’s block, regardless of whether the condition matches.”
Internals / What Actually Happens
When Go’s compiler sees fallthrough, it:
- Executes the current case block.
- Jumps directly to the start of the next case block, skipping its condition check.
- Executes that block fully.
- Stops unless another fallthrough is written at the end.
So it’s like a forced jump (goto) to the next case.
num := 1
switch num {
case 1:
fmt.Println("One")
fallthrough
case 2:
fmt.Println("Two")
fallthrough
case 3:
fmt.Println("Three")
}
Even though num = 1, Go executed all three blocks because of chained fallthrough.
fallthrough in Go is a manual instruction: “Don’t stop after this case; run the very next case’s code too (ignore its condition).”
-
A defer statement defers the execution of a function until the surrounding function returns.
-
The deferred call's arguments are evaluated immediately, but the function call is not executed until the surrounding function returns.
func main() {
defer fmt.Println("world")
fmt.Println("hello")
}
when their are multiple defer functions then Deferred function calls are pushed onto a stack. When a function returns, its deferred calls are executed in last-in-first-out order.
func main() {
fmt.Println("counting")
for i := 0; i < 10; i++ {
defer fmt.Println(i)
}
fmt.Println("done")
}
Check out [https://go.dev/blog/defer-panic-and-recover] for more details on Defer, Panic and Recover.
