Go Tutorial Part 3 (Structs, Pointers and References, Maps, Structs vs Maps in Go)

GO - Part 3

Credit goes to - Master the fundamentals and advanced features of the Go Programming Language (Golang), on Udemy by Stephen Grider.
I have tried some snippets on my own and some are referring to the snippets developed while going through the course.

Code Repo: https://github.com/namitsharma99/goLangTutorials



Structs data structure
- - - - - - - - - - - - - - - - - - 
- collection of properties related together

2 steps to define structs:
1. provide GO, the fields struct should have
2. create the object using the above


main.go
- - - - 

package main

import "fmt"

type person struct {
  firstName string
  lastName string
}

func main() {
  buddy := person {"code", "buddy"} // not a good practice as it depends on positions
  namit := person {firstName: "Namit", lastName: "Sharma"}

  fmt.Println(buddy)
  fmt.Println(namit)
}

O/P
- - - 

$ go build
$ ls
  main.go structs
$ ./structs 
  {code buddy}
  {Namit Sharma}

For uninitialized structs, if we want to see the struct signature - 

...
  var human person
  fmt.Println(human)
  fmt.Printf("%+v", human)
...

o/p
- - -
{ }
{firstName: lastName:}


...
  human.firstName = "ABC"
  human.lastName = "DEF"

  fmt.Println(human)
  fmt.Printf("%+v", human)
...

o/p
- - -
{ABC DEF}
{firstName:ABC lastName:DEF}




Nested Structs
- - - - - - - - - - - - -

package main

import "fmt"

type contactInfo struct {
  email string
  zipCode int
}

type person struct {
  firstName string
  lastName string
  contact contactInfo
}

func main() {
 
  newPerson := person {
    firstName:"Namit",
    lastName:"Sharma",
    contact: contactInfo {
      email: "thecodebuddy.blogspot.in",
      zipCode: 60001,
    },
  }
  // multiline declarations should have commas at the end
  
  fmt.Println("%+v", newPerson)

}

o/p
- - -

$ ./main 
%+v {Namit Sharma {thecodebuddy.blogspot.in 60001}}


Note - if the name of the variable is same as the type name, just use type - 

package main
import "fmt"

type contactInfo struct {
  email string
  zipCode int
}

type person struct {
  firstName string
  lastName string
  contactInfo
}

func main() {

newPerson := person {
    firstName:"Namit",
    lastName:"Sharma",
    contactInfo: contactInfo {
      email: "thecodebuddy.blogspot.in",
      zipCode: 60001,
    },
  }
  // multiline declarations should have commas at the end

  fmt.Printf("%+v", newPerson)
  fmt.Println("")

}

o/p
- - -

$ ./main 
{firstName:Namit lastName:Sharma contactInfo:{email:thecodebuddy.blogspot.in zipCode:60001}}



 
Structs and Receiver Functions
- - - - - - - - - - - - - - - - - - - - - - - - - - 

func main () {
...
  fmt.Printf("%+v", newPerson)
  fmt.Println("")
  newPerson.print()
...
}

o/p
- - - 

{firstName:Namit lastName:Sharma contactInfo:{email:thecodebuddy.blogspot.in zipCode:60001}}
{firstName:Namit lastName:Sharma contactInfo:{email:thecodebuddy.blogspot.in zipCode:60001}}




Updating values inside struct
- - - - - - - - - - - - - - - - - - - - - - - - -

func (p person) updateName(newFirstName string) {
  p.firstName = newFirstName
}


This fails as there is another memory allocated to the changes made, original reference has no impact (pass by copy), therefore use pointers

...
  fmt.Println("updating name::")
  newPersonPointer := &newPerson  // Optional to define a pointer to person, func can accept the person object as well
  newPersonPointer.updateName("XYZ")
  newPersonPointer.print()
...

func (ptr *person) updateName(newFirstName string) {
  (*ptr).firstName = newFirstName
}


o/p
- - -
updating name::
{firstName:XYZ lastName:Sharma contactInfo:{email:thecodebuddy.blogspot.in zipCode:60001}}


Explanation -

& operator : memory address of variable
* operator : value at the address

Rules:
1. To turn address into value, use *address
2. To turn value into address, use &value



Note::

Pointers are not required while working with Slices
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Slices internally use Arrays

Slice = length | capacity | ptr to head of array

Now while making any change to slices, a copy of slice is created, but still it is pointing to the actual address
Hence it works without any fail.
Therefore, a slice is called as of 'Reference Type'.

Value Types: int, float, string, bool, structs  (use pointers while working with these)
Reference Types: slices, maps, channels, pointers, functions




Maps
- - - - -

All keys of same type
All values of same type


main.go
-------
package main

import "fmt"

func main() {
  colors := map[string] string {
    "red" : "#ff0000",
    "green" : "#433243",
  }
  fmt.Println(colors)
}

O/P
- - -
$ ./main 
map[green:#433243 red:#ff0000]


Also, map be declared as - 
1. var colors map[string] string
2. colors := make(map[string]string)

func main() {
  // colors := map[string] string {
  //   "red" : "#ff0000",
  //   "green" : "#433243",
  // }

  // var colors map[string] string
  colors := make(map[string]string)

  colors["white"] = "#ffffff"
  colors["grey"] = "#222222"
  fmt.Println(colors)

  delete(colors, "white")  // to delete using a key
  fmt.Println(colors)
}

O/P
- - -
$ ./main 
map[grey:#222222 white:#ffffff]
map[grey:#222222]



Map Iteration
- - - - - - - - - - - -

func printMap (c map[string]string ) {
  for color, hex := range c {
    fmt.Println("Hex code for ", color, "is ", hex)
  }
}

main.go
...
printMap(colors)
...

o/p
- - -
$ ./main 
map[grey:#222222 white:#ffffff]
Hex code for  white is  #ffffff
Hex code for  grey is  #222222



Map vs Structs
- - - - - - - - - - - - 

Map - 
  • same typed keys
  • same typed values
  • keys are indexed and iterable
  • used to represent collection of related properties
  • no need to have all keys available at compile time
  • reference type

Struct -
  • diff types of values
  • keys are not indexed
  • can be used to represent collection of different properties
  • no need to know all the different fields at compile time
  • value type



No comments:

Post a Comment

Featured post

Oracle SQL Scheduled Jobs - An Interesting Approach

  Oracle SQL Scheduled Jobs A DB Scheduler is the best way to automate any backend database job. For instance, if you want to process the p...