Friday, September 4, 2015

Embedded or Anonymous Fields in Structs

For an introduction to Structs read: Go Structs   


Go supports anonymous or embedded field - i.e. a field without a name but with a type. You can say that the type itself is a name.

Why Anonymous or Embedded Fields or Composition?


Yes, Embedded fields, Composition or Anonymous fields are different names for same concept.

If you're familiar with object oriented programming you can relate an anonymous or embedded field with Inheritance and its single biggest advantage is code re-usability. 

CodeRef# 1


package main

import "fmt"

type person struct {
 name   string
 gender string
 age    int
}

type employee struct {
 person //embedded field
 salary float64
 dept   string
}

func main() {
 empProfile := employee{person{"Jack", "M", 32}, 3000, "Electronics"}
 fmt.Println(empProfile)
 fmt.Printf("%s works in %s department. Salary: %.2f\n", empProfile.name, empProfile.dept, empProfile.salary)
}

Output

{{Jack M 32} 3000 Electronics}
Jack works in Electronics department. Salary: 3000.00

Play with the above code

CodeRef# 2


package main

import "fmt"

type person struct {
 name   string
 gender string
 age    int
}

type employee struct {
 person //embedded field
 salary float64
 dept   string
}

type manager struct {
 employee //embedded field
 numEmp int
}

func main() {
 empProfile := employee{person{"Jack", "M", 32}, 3000, "Electronics"}
 mgr := manager{employee{person{"Bill", "M", 55}, 5000, "CSc"},21}
 fmt.Printf("%s works in %s department. Salary: %.2f\n", empProfile.name, empProfile.dept, empProfile.salary)
 fmt.Printf("%s manages %s department with %d employees. Salary: %.2f", mgr.name, mgr.dept, mgr.numEmp, mgr.salary,)
}

Output
Jack works in Electronics department. Salary: 3000.00
Bill manages CSc department with 21 employees. Salary: 5000.00
Play with the code here
What Happens in Case of a Field with the Same Name in Two Structs?
For example see the following: 
A field named location exists in both the structs (person and employee). 
  • What happens when you call empProfile.location? 
  • Which location gets a precedence?
RefCode# 3
package main
import "fmt"

type person struct {
 name, gender, location  string
}

type employee struct {
 person //embedded field
 salary float64
 dept   string
 location string
}

func main() {
 empProfile := employee{person{"Jack", "M", "Chicago"}, 3000, "M", "New York"}
 fmt.Printf("%s. Current location: %s\n", empProfile.name, empProfile.location)
 fmt.Printf("%s. Native location: %s\n", empProfile.name, empProfile.person.location)
}

Jack. Current location: New York
Jack. Native location: Chicago
Play with the code here
As it is evident from the above output, the child field (i.e. the location from employee) takes precedence over the parent (i.e. person). In Object Oriented parlance this provides a way to override a field or method.
If you liked it, spread the word about it. Happy coding!

No comments:

Post a Comment