In reviewing this code which was part of some instruction on interfaces, I also had to review switch statements.
The following code was given as an example of “switch on a value”
This is for switch instructions based on variable’s data type. The variable is h and the .(type) is simply an instruction to get the data type of h. Hence,
switch h.(type) {
case person:
fmt.Println("I was passed into barrrrrr", h.(person).first)
case secretAgent:
fmt.Println("I was passed into barrrrrr", h.(secretAgent).first)
}
Allows you to switch when h variable is holding a person data type or secretAgent data type. Both of them are the structures.
type is data type, as in int, int8, int16, int32, string, byte, []byte, …
Switch is a simple switch statement, the other question which is . is a type assertion.
Rule 1: h must be an interface type, because of that: type assertion needs an interface. When you call h.(type), you are trying to retrieve the interface value’s underlying concrete type.
Let’s say you get an interface value from a function: h:=getBirthDay()
and you are wondering whether this function returns birthday in string or time.
switch bd.(type) {
case time.Time:
birthDay = bd.(time.Time)
case string:
t, _ := time.Parse(timeLayout, bd.(string))
birthDay = t
default:
fmt.Printf("unexpected time: %T\n", bd)
}
h.(type) is a special case and you can use it only with switch.
compiler won’t allow you to do that: t := h.(type) on a line without switch
another use of the synax is concrete type checking or type assertion:
var timeLayout = "2006-01-02"
h := getBirthDay()
var birthDay time.Time
if v, ok := h.(time.Time); ok {
fmt.Println("it is Time. let''s set birthDay")
birthDay = v
} else if v, ok := h.(string); ok {
fmt.Println("it is string let's parse it")
birthDay, _ = time.Parse(timeLayout, v)
} else {
fmt.Println("upps something is wrong")
return
}
fmt.Println(birthDay.Format(timeLayout))