Slices have a length (number of elements) and a capacity (size of the underlying array). The initial capacity defaults to the initial length.
Appending beyond the current capacity allocates a larger (2x) array and copies elements to a new memory location. This is a performance-heavy operation.
func main() { a := make([]int, 5, 7) fmt.Println("a:", a) // a: [0 0 0 0 0] b := append(a, 1) fmt.Println("b:", b) // b: [0 0 0 0 0 1] c := append(a, 2) fmt.Println("a:", a) // a: [0 0 0 0 0] fmt.Println("b:", b) // b: [0 0 0 0 0 2] (b got updated because of c) fmt.Println("c:", c) // c: [0 0 0 0 0 2]}
Here, a has remaining capacity, b and c share the same backing array. Appending through one affects the other.
This unexpected behavior would not occur if there was not enough capacity for the new element. In that case, Go would allocate a new array and copy the existing elements to it, resulting in new addresses. But still, it is prone to go unexpected.
Maps in Go are unordered collections of key-value pairs.
Syntax:
map[keyType]valueType
Initialize:
m := make(map[string]int)
Or
m := map[string]int{}
Or with values:
m := map[string]int{ "one": 1, "two": 2, "three": 3,}
Maps must be initialized first (empty or with values) to make them ready to use. Declaring a map with var m map[string]int and then assigning values causes a panic: assignment to entry in nil map.
Struct tags are metadata attached to struct fields. They are typically used by packages like encoding/json to control encoding and decoding behavior.
By default, Go encodes fields using their names. When fields must be capitalized but require different names in output formats, struct tags define the external representation.
type User struct { Id int `json:"id"` // same but lowercase Name string `json:"full_name"` // renamed field Email string `json:"email,omitempty"` // omitted if empty ("") Password string `json:"-"` // ignored completely Age int `json:"age,string,omitempty"` // encoded as string Salary int `json:"salary,omitempty"` // omitted if 0 Score *int `json:"score,omitempty"` // nil omitted, 0 still included}func main() { score := 0 myUser := User{ Id: 1, Name: "John", Email: "[email protected]", Password: "12345", Age: 26, Salary: 0, Score: &score, } fmt.Printf("myUser: %+v\n", myUser) // myUser: {Id:1 Name:John Email:[email protected] Password:12345 Age:26 Salary:0 Score:0x255956d3e048} jUser, _ := json.Marshal(myUser) // Converting struct to JSON fmt.Printf("jUser: %+v\n", string(jUser)) // jUser: {"id":1,"full_name":"John","email":"[email protected]","age":"26","score":0}}
The json package only accesses the exported fields of struct types (those that begin with an uppercase letter).
omitempty can hide valid values like 0 or false. Using a pointer with omitempty omits only nil while keeping
other values.