Question:

What is wrong with the following code snippet?

type Orange struct {
	Quantity int
}

func (o *Orange) Increase(n int) {
	o.Quantity += n
}

func (o *Orange) Decrease(n int) {
	o.Quantity -= n
}

func (o *Orange) String() string {
	return fmt.Sprintf("%v", o.Quantity)
}

func main() {
	var orange Orange
	orange.Increase(10)
	orange.Decrease(5)
	fmt.Println(orange)
}

Provide the proper code solution.

Answer:

This is a trick question because you might think this has something to do with the member variable Quantity being set incorrectly, but actually, it will be set to 5 as expected. The real problem here, which is easy to overlook, is that the String() method that implements the fmt.Stringer() interface will not be invoked when the object orange is being printed with fmt.Println() function, because the method String() is not being defined on a value but only on a pointer:

var orange Orange
orange.Increase(10)
orange.Decrease(5)
fmt.Println(orange)
// Output: {5}

orange := &Orange{}
orange.Increase(10)
orange.Decrease(5)
fmt.Println(orange)
// Output: 5

That is a subtle one, but the fix is simple. You need to redefine the String() method on a value instead of a pointer, and in that case, it will work for both pointers and values:

func (o Orange) String() string {
	return fmt.Sprintf("%v", o.Quantity)
}

Keywords:

© 2017 QuizBucket.org