Basics datatypes | Spec term | What it covers | |---|---| | **Basic types** (predeclared) | `bool`, `string`, numeric types (`int`, `uint`, `float`, `complex`, `byte`, `rune`) | | **Composite types** (via type literals) | array, struct, pointer, function, interface, slice, map, channel | **Variables** There are mainly 3 data types ie bool, Numeric (int and float32) and string. There are 2 ways to declare a variable 1. with var keyword `var variablename type = value`(with initial value) or `var variablename type`(with no initial value) 2. with `:=` sign `variablename := value ` . data type is assigned with initial value type so there is no way to declare it without initial value. Also this method can be only used inside a function eg ```go package main import ("fmt") func main() { var student1 string = "John" //type is string var student2 = "Jane" //type is inferred x := 2 //type is inferred fmt.Println(student1) fmt.Println(student2) fmt.Println(x) } ``` for multiple values ```go var a, b, c, d int = 1, 3, 5, 7 ``` or ```go var ( a int b int = 1 c string = "hello" ) ``` Similarly there are constants whose value cant be changed and is read-only it dont have that `:=` thing and can be even defined without type ```go const ( A int = 1 B = 3.14 C = "Hi!" ) ```   Output functions It has `Print`, `Println` and `Printf` ```go func main() { var i string = "Hello" fmt.Printf("i has value: %v and type: %T\n", i, i) } ``` %v and %T are formatting verbs ```txt %v Prints the value in the default format %#v Prints the value in Go-syntax format %T Prints the type of the value %% Prints the % sign ``` ```go package main import ("fmt") func main() { var i = 15.5 var txt = "Hello World!" fmt.Printf("%v\n", i) fmt.Printf("%#v\n", i) fmt.Printf("%v%%\n", i) fmt.Printf("%T\n", i) fmt.Printf("%v\n", txt) fmt.Printf("%#v\n", txt) fmt.Printf("%T\n", txt) } ```   **Data types** 1. Integers `int`, `uint` for signed and unsigned integers . Also `int8`, `int16`, .. 2. Float ```go func main() { var x float64 = 1.7e+308 fmt.Printf("Type: %T, value: %v", x, x) } ```   ### Arrays Syntax ```go var array_name = [length]datatype{values} // here length is defined // or var array_name = [...]datatype{values} // here length is inferred // or array_name := [length]datatype{values} // here length is defined // or array_name := [...]datatype{values} // here length is inferred ``` eg ```go func main() { var arr1 = [3]int{1,2,3} arr2 := [...]int{4,5,6,7,8} // or // declaring a array with no initialization var a [5]int fmt.Println(arr1) fmt.Println(arr2) } ``` in case of integer array, if all the elements are not initialized then those remaining ones will be filled with 0. To initialize specific elements ```go func main() { arr1 := [5]int{1:10,2:40} fmt.Println(arr1) // to get length of array fmt.Println(len(arr1)) } ``` Output `[0 10 40 0 0] `   and to find element position in array `index := slices.Index(myArray[:], target)` and for array of structs ```go index := slices.IndexFunc(users[:], func(u User) bool { return u.ID == targetID }) ``` **Slices** Slices are like arrays and unlike arrays its size can grow or shrink. It has length and capacity thing. Syntax ```go slice_name := []datatype{values} and slice_name := make([]type, length, capacity) ``` example ```go func main() { myslice1 := []int{} fmt.Println(len(myslice1)) fmt.Println(cap(myslice1)) fmt.Println(myslice1) myslice2 := []string{"Go", "Slices", "Are", "Powerful"} fmt.Println(len(myslice2)) fmt.Println(cap(myslice2)) fmt.Println(myslice2) myslice3 := make([]int, 5, 10) } ``` to change or access elements it is same as arrays. To append elemnts use append function `slice_name = append(slice_name, element1, element2, ...)` or `slice3 = append(slice1, slice2...)`   For changing the length of array ```go func main() { arr1 := [6]int{9, 10, 11, 12, 13, 14} // An array myslice1 := arr1[1:5] // Slice array fmt.Printf("myslice1 = %v\n", myslice1) fmt.Printf("length = %d\n", len(myslice1)) fmt.Printf("capacity = %d\n", cap(myslice1)) myslice1 = arr1[1:3] // Change length by re-slicing the array fmt.Printf("myslice1 = %v\n", myslice1) fmt.Printf("length = %d\n", len(myslice1)) fmt.Printf("capacity = %d\n", cap(myslice1)) myslice1 = append(myslice1, 20, 21, 22, 23) // Change length by appending items fmt.Printf("myslice1 = %v\n", myslice1) fmt.Printf("length = %d\n", len(myslice1)) fmt.Printf("capacity = %d\n", cap(myslice1)) neededNumbers := arr3[:len(arr3)-4] numberCopy := make([]int, len(neededNumbers)) copy(numberCopy, neededNumbers) // or // neededNumbers... is like ...arr in js numberCopy = append([]int(nil), neededNumbers...) fmt.Printf("numberCopy = %v\n", numberCopy) fmt.Printf("length = %d\n", len(numberCopy)) fmt.Printf("capacity = %d\n", cap(numberCopy)) fmt.Println("for neededNumbers:") fmt.Printf("capacity = %d\n", cap(neededNumbers)) } ``` Capacity will increase too automatically   Memory Efficiency When copying elements from array, by default go will load all elements to memory so in order to copy few elements from large array it is better to use copy function.   **runes** character array of string but containing ascii code instead of characters ```go import "unicode/utf8" str:= "AB" runes:= []rune(str) // [65 66] buf := make([]byte, utf8.RuneLen(runes[0])) utf8.EncodeRune(buf, runes[0]) // [65] fmt.Println("string form: ", string(runes)) // AB byteSlice := []byte(string(runes)) // [65 66] as character array fmt.Printf("%c\n", runes) // [A B] // to string slice sli := strings.Split(str, "") // [A B] -> not rune slice but string slice slistr := strings.Join(sli, "") // AB ``` byteslice is of utf8 so takes mostly text but rune slice covers much as its int32