Menu
Coddy logo textTech

Value Semantics

Part of the Object Oriented Programming section of Coddy's Swift journey. Lesson 8 of 57.

Structs are value types: assigning a struct to another variable copies it. Changing the copy leaves the original unchanged, unlike a class:

struct Point {
    var x: Int
}

var a = Point(x: 1)
var b = a
b.x = 99
print(a.x)
print(b.x)

Output:

1
99

The same comparison with a class shows the difference: both variables refer to one object.

class PointRef {
    var x: Int
    init(x: Int) { self.x = x }
}

let a = PointRef(x: 1)
let b = a
b.x = 99
print(a.x)

Output:

99

Passing a struct to a function also passes a copy. The parameter is a constant, so to return a changed version the function makes a local copy and returns it:

struct Point {
    var x: Int
}

func shifted(_ p: Point, by dx: Int) -> Point {
    var copy = p
    copy.x += dx
    return copy
}

let start = Point(x: 1)
let moved = shifted(start, by: 4)
print(start.x)
print(moved.x)

Output:

1
5

Arrays of structs hold independent values. Changing an element through its index changes only that element, and copying the array copies every value:

struct Score {
    var points: Int
}

var round1 = [Score(points: 1), Score(points: 2)]
var round2 = round1
round2[0].points = 50
print(round1[0].points)
print(round2[0].points)

Output:

1
50
challenge icon

Challenge

Easy

Complete tryDiscount(_:percent:). It receives a Price struct, and returns a discounted copy: the cents reduced by the percentage, rounded down. The supplied code prints the original and the discounted price, so the original must stay unchanged.

The supplied code reads a price in cents and one percentage per line, and prints was 1000, now 900 for each.

Your code goes in Price.swift and Functions.swift. main.swift holds the supplied input/output code and cannot be edited.

Try it yourself

// Supplied input/output code: keep it as it is
var input: [String] = []
while let line = readLine() { input.append(line) }
let original = Price(cents: Int(input[0])!)
for line in input.dropFirst() {
    let cheaper = tryDiscount(original, percent: Int(line)!)
    print("was \(original.cents), now \(cheaper.cents)")
}
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Object Oriented Programming

Practice on your own: Swift playground