I'm working through a design patterns book and trying to apply the patterns to Go as a way to learn both.
Currently I have reached the decorator pattern and I ran into a scenario I was curious about.
Here is some sample code:
type Beverage interface {
getDescription() string
cost() float64
}
type HouseBlend struct{}
func (hb *HouseBlend) getDescription() string {
return "House Blend Coffee"
}
func (hb *HouseBlend) cost() float64 {
return .89
}
type Mocha struct {
b Beverage
}
func (m *Mocha) getDescription() string {
return m.b.getDescription() ", Mocha"
}
func (m *Mocha) cost() float64 {
return m.b.cost() .20
}
What is the difference between
var hb Beverage = &HouseBlend{}
//This works since hb is an interface type
hb = &Mocha{
b: hb,
}
And
hb := &HouseBlend{}
//This assignment fails since Mocha is not type HouseBlend
hb = &Mocha{
b: hb,
}
This also works
hb := *new(Beverage)
hb = &Espresso{}
hb = &Mocha{
b: hb,
}
Is there a shorthand way of giving my variable hb the interface type or does it need to be explicit in order to be able to "decorate" my struct and reassign the variable to different types?
Any suggestions on improving the decorator pattern here and achieving clean polymorphism are welcome. Thank you!
CodePudding user response:
var hb Beverage
is how you explicitly give the variable a type. Implicit typing will always get the type of the value you put into it. I'm not sure what you're looking for in terms of "shorthand" here, as var name Type
is already pretty short, but if you really want to use a short variable declaration you could use a type conversion:
hb := Beverage(&HouseBlend{})
CodePudding user response:
You can use the short form and declare hb
as an interface using:
hb:=Beverage(&HouseBlend{})
This piece of code is not exactly correct:
// You allocate a pointer to an interface, and redirect it to get an uninitialized interface value
hb := *new(Beverage)
// Here, you throw away the value of the first assignment
hb = &Espresso{}