Start learning free

LESSON 402 OF 404 · PROJECTS: OBJECT-ORIENTED

Shopping Cart in Go in Go

Practice

A shop keeps its orders in a cart. Build two types that work together: a LineItem is one row of the cart (a product, its price and how many were bought), and a Cart holds many rows and adds them up. The cart has line items (composition), it is not one.

LineItem

  • A struct LineItem with fields name string, price float64, quantity int.
  • func (item LineItem) subtotal() float64 returns item.price * float64(item.quantity).

Cart

  • A struct Cart with one field items []LineItem. The empty value Cart{} is an empty cart.
  • func (cart *Cart) add(item LineItem) appends the item to cart.items. It uses a pointer receiver (*Cart) so the change is kept in the caller's cart.
  • func (cart Cart) total() float64 returns the sum of the subtotals of all items: start total := 0.0, loop with for _, item := range cart.items, return total.

Rules:

  • The total is worked out every time it is asked for, from the items in the cart at that moment. Adding an item later changes the next total.
  • An empty cart has a total of 0.
  • An item with price 5 and quantity 3 has a subtotal of 15.
  • Prices in the driver are whole numbers.

Go has no classes: structs plus methods play that role. The driver is mainFunction() and prints with strconv.Itoa(int(...)) to show whole numbers.

The driver (already in the starter code, don't change it) creates an empty cart, checks one subtotal, then fills a cart and prints the total twice:

func mainFunction() {
	empty := Cart{}
	fmt.Println("Empty: " + strconv.Itoa(int(empty.total())))
	apple := LineItem{name: "Apple", price: 5, quantity: 3}
	fmt.Println("Subtotal: " + strconv.Itoa(int(apple.subtotal())))
	cart := Cart{}
	cart.add(apple)
	cart.add(LineItem{name: "Bread", price: 20, quantity: 3})
	fmt.Println("Total: " + strconv.Itoa(int(cart.total())))
	cart.add(LineItem{name: "Milk", price: 10, quantity: 2})
	fmt.Println("Total: " + strconv.Itoa(int(cart.total())))
}

Expected output:

Empty: 0
Subtotal: 15
Total: 75
Total: 95

Declare the two structs first, then the methods.

for _, item := range cart.items { total += item.subtotal() }

type LineItem struct {
	name     string
	price    float64
	quantity int
}

func (item LineItem) subtotal() float64 {
	return item.price * float64(item.quantity)
}

type Cart struct {
	items []LineItem
}

func (cart *Cart) add(item LineItem) {
	cart.items = append(cart.items, item)
}

func (cart Cart) total() float64 {
	total := 0.0
	for _, item := range cart.items {
		total += item.subtotal()
	}
	return total
}

func mainFunction() {
	empty := Cart{}
	fmt.Println("Empty: " + strconv.Itoa(int(empty.total())))
	apple := LineItem{name: "Apple", price: 5, quantity: 3}
	fmt.Println("Subtotal: " + strconv.Itoa(int(apple.subtotal())))
	cart := Cart{}
	cart.add(apple)
	cart.add(LineItem{name: "Bread", price: 20, quantity: 3})
	fmt.Println("Total: " + strconv.Itoa(int(cart.total())))
	cart.add(LineItem{name: "Milk", price: 10, quantity: 2})
	fmt.Println("Total: " + strconv.Itoa(int(cart.total())))
}

STEP 1 OF 15
    Ctrl + Enter to check

    Shopping Cart in Go

    Keep going with GoAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free