Chapter 8 - Structs

Exercise 2: Modifying Structs from Functions

All squares are rectangles, but not all rectangles are squares… Let’s define a makeSquare function that takes a rectangle and “cuts it down” so that its longer sides are equal to its shorter sides.

  • If the rectangle’s length is greater than its width, set its length equal to its width.
  • Otherwise, set the width equal to the length.

makeSquare won’t return a value; it should modify the rectangle it receives (meaning it will need to accept a pointer to a rectangle and modify the value at that pointer).

In main, create a couple different rectangle values, one where the length is greater and one where the width is greater, and try converting them to squares using makeSquare.

Solution

package main

import "fmt"

type rectangle struct {
	length float64
	width  float64
}

func rectangleInfo(r rectangle) {
	fmt.Println("Length:", r.length)
	fmt.Println("Width:", r.width)
}

// Accepts a pointer to a rectangle rather than a
// rectangle value, so that it can modify the original
// value at the pointer.
func makeSquare(r *rectangle) {
	// Remember that the dot operator works the same
	// with a pointer to a struct as it does with the
	// actual struct. You don't have to explicitly
	// write (*r).length or (*r).width.
	if r.length > r.width {
		r.length = r.width
	} else {
		r.width = r.length
	}
}

func main() {
	// Make a rectangle that's longer than it is wide.
	var r rectangle
	r.length = 4.2
	r.width = 2.3
	rectangleInfo(r)
	makeSquare(&r) // Pass a pointer to makeSquare.
	rectangleInfo(r)
	// Make a rectangle that's wider than it is long.
	var r2 rectangle
	r2.length = 10
	r2.width = 20
	rectangleInfo(r2)
	makeSquare(&r2) // Pass a pointer to makeSquare.
	rectangleInfo(r2)
}

Output:

Length: 4.2
Width: 2.3
Length: 2.3
Width: 2.3
Length: 10
Width: 20
Length: 10
Width: 10