5.8 KiB
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
- with var keyword
var variablename type = value(with initial value) orvar variablename type(with no initial value) - with
:=signvariablename := 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
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
var a, b, c, d int = 1, 3, 5, 7
or
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
const (
A int = 1
B = 3.14
C = "Hi!"
)
Output functions
It has Print, Println and Printf
func main() {
var i string = "Hello"
fmt.Printf("i has value: %v and type: %T\n", i, i)
}
%v and %T are formatting verbs
%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
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
- Integers
int,uintfor signed and unsigned integers . Alsoint8,int16, .. - Float
func main() {
var x float64 = 1.7e+308
fmt.Printf("Type: %T, value: %v", x, x)
}
Arrays
Syntax
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
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
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
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
slice_name := []datatype{values}
and
slice_name := make([]type, length, capacity)
example
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
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
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