Creating a map<\/li>\n<\/ul>\n\/\/ make(map[keyType]valueType)\n\nnameToAge := make(map[string]int)\n\n\/\/ short hand declaration\nfileSizes := map[string]int{\n\t"file1.txt": 104,\n\t"file2.txt": 4224, \/\/<-- notice the trailing comma!\n}\n<\/code><\/pre>\n\nAdding items to the map or updating existing values<\/li>\n<\/ul>\nnameToAge["jannie"] = 23\nnameToAge["koos"] = 34\nfmt.Println(nameToAge) \/\/ map[jannie:23 koos:34]\n\nnameToAge["jannie"] = 42\nfmt.Println(nameToAge) \/\/ map[jannie:42 koos:34]\n<\/code><\/pre>\n\nAny comparable type is allowed to be used as a key type. Including your own \u201cstruct\u201d types.<\/li>\n The zero value of a map is nil<\/code> and maps have to be initialized first.<\/li>\nGetting items from a map.<\/li>\n<\/ul>\nageForKoos := nameToAge["koos"]\n\n\/\/ What about when the key does not exist?\n\/\/ It returns the zero value of the type\nfmt.Println(fileSizes["unknown"]) \/\/ 0\n<\/code><\/pre>\n\nChecking if an item exists in the map.<\/li>\n<\/ul>\nvalue, ok := nameToAge["unknown"]\nif ok {\n... \/\/ key "unknown" existed and we received a value in value\n}\n\n\/\/ or to just check if key is present\n_, exists := someMap[someKey]\nif exists { ...\n<\/code><\/pre>\n\nIterating over the key-value pairs<\/li>\n<\/ul>\nfor key, value := range nameToAge {\n...\n}\n<\/code><\/pre>\n\nMap is unordered.<\/li>\n Use delete(map, key)<\/code> function to delete an item from a map.<\/li>\n<\/ul>\ndelete(nameToAge, "koos")\n\n\/\/ No runtime error is raised if you delete a non existent key\n\/\/ Also delete doesn't return a value to check if the key was deleted\ndelete(nameToAge, "no-error")\n<\/code><\/pre>\n\nUse len(map)<\/code> function to get the key count.<\/li>\nNOTE:<\/strong> Maps are reference types (unlike Swift). Meaning that if you assign a map to multiple variables (or pass to functions) then changes made to one will reflect to all of them (since they are references to the actual data).<\/li>\nMaps can not be compared using ==<\/code> operator. The ==<\/code> operator can only be used to check if the map is nil<\/code><\/li>\n<\/ul>\nStrings<\/h3>\n\nStrings are implemented as a slice of bytes in Go.<\/li>\n string<\/code> is the type.<\/li>\nStrings are unicode compliant and encoded as UTF-8.<\/li>\n<\/ul>\nname := "Andre Jacobs"\nfmt.Printf("my name is %s\\n", name)\n<\/code><\/pre>\n\nUse len()<\/code> to get the number of bytes in the string.<\/li>\nNOTE:<\/strong> Iterating over the bytes of a string is not the same as iterating over \u201ccharacters\u201d or unicode code points (as what Swift does).<\/li>\nTo iterate over the unicode code points, you will use the rune<\/code> type (alias to int32<\/code>).<\/li>\n<\/ul>\nfunc printCharacters(s string) { \n runes := []rune(s)\n for i := 0; i < len(runes); i++ {\n fmt.Printf("%c ", runes[i])\n }\n}\n\n\/\/ A much better way is to use range\nfor index, rune := range s {\n...\n}\n<\/code><\/pre>\n\nCreating a string from a slice of bytes.<\/li>\n<\/ul>\nbyteSlice := []byte{0x43, 0x61, 0x66, 0xC3, 0xA9}\nstr := string(byteSlice)\n<\/code><\/pre>\n\nCreating a string from a slice of runes.<\/li>\n<\/ul>\nruneSlice := []rune{0x0053, 0x0065, 0x00f1, 0x006f, 0x0072}\nstr := string(runeSlice)\n<\/code><\/pre>\n\nUse RuneCountInString()<\/code> function from package \u201cunicode\/utf8\u201d to get the number of unicode \u201ccharacters\u201d in a string.<\/li>\nYou can use ==<\/code> to check for equality. (May assumption is Go just compares the bytes and no the grapheme clusters like Swift does).<\/li>\nYou can concatenate strings using +<\/code> operator. You can also use fmt.Sprintf function.<\/li>\nString are immutable.<\/li>\n<\/ul>\nPointers<\/h3>\n\nQuick recap: A pointer is a variable that stores an address to some location in memory (that can then be mapped to a type).<\/li>\n Declared using *T<\/code>.<\/li>\nUse &<\/code> to get the address of a variable.<\/li>\n<\/ul>\nb := 255\nvar a *int = &b \/\/ create a pointer to b\nfmt.Printf("Type of a is %T\\n", a) \/\/ Type of a is *int\nfmt.Println("address of b is", a) \/\/ address of b is 0xc000018030\n<\/code><\/pre>\n\nZero value of a pointer is nil<\/code>.<\/li>\nAllocate a new instance and assign to a pointer using new<\/code> function.<\/li>\nDereference using *<\/code> just like C.<\/li>\n<\/ul>\np := new(int)\nfmt.Printf("%T\\n", p) \/\/ *int\nfmt.Println(p) \/\/ 0xc000018038\nfmt.Println(*p) \/\/ 0\n\n*p = 42\nfmt.Println(*p) \/\/ 42\n<\/code><\/pre>\n\nPointers can be passed as function arguments.<\/li>\n Pointers can also be returned as the result type for a function.<\/li>\n<\/ul>\n\/\/ What do you think this code will do?\nfunc spideySense() *int {\n i := 5\n return &i\n}\n\n\/\/ Go is smart enough to save you from the C pitfalls here and\n\/\/ allocates i on the heap!\n<\/code><\/pre>\n\nIt is more Go idiomatic to pass slices of arrays to functions (instead of passing a pointer to an array).<\/li>\n Go does not support pointer arithmetic like C does.<\/li>\n<\/ul>\n<\/div>\n","protected":false},"excerpt":{"rendered":"Featured image by\u00a0Egon Elbre […]<\/p>\n
Read more →<\/a><\/p>\n","protected":false},"author":2,"featured_media":551,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_mi_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[52],"tags":[53],"yoast_head":"\nLearning Go - Day 2 - Andr\u00e9 Jacobs<\/title>\n \n \n \n \n \n \n \n \n \n \n \n\t \n\t \n\t \n \n \n \n \n \n\t \n\t \n\t \n