Value Semantics
Returned Copy
A method can return an updated copy instead of changing the original value.
Build an updated value
returned_copy.swift
Replay: real traced execution (multi-file project)
struct Settings {
var level: Int
func withLevel(_ nextLevel: Int) -> Settings {
var copy = self
copy.level = nextLevel
return copy
}
}
let selectedLevel = 2
let base = Settings(level: 0)
let updated = base.withLevel(selectedLevel)
let message = "base=\(base.level), updated=\(updated.level)"
print(message)
struct Settings {
var level: Int
func withLevel(_ nextLevel: Int) -> Settings {
var copy = self
copy.level = nextLevel
return copy
}
}
let selectedLevel = 1
let base = Settings(level: 0)
let updated = base.withLevel(selectedLevel)
let message = "base=\(base.level), updated=\(updated.level)"
print(message)
struct Settings {
var level: Int
func withLevel(_ nextLevel: Int) -> Settings {
var copy = self
copy.level = nextLevel
return copy
}
}
let selectedLevel = 4
let base = Settings(level: 0)
let updated = base.withLevel(selectedLevel)
let message = "base=\(base.level), updated=\(updated.level)"
print(message)
selectedLevel ← 2, base ← Settings(level: 0)
11let selectedLevel→ 2 = 2 //@selectedLevel=1, 412let base→ Settings(level: 0) = Settings(level: 0)13let updated = baseSettings(level: 0).withLevel(selectedLevel2)14let message = "base=\(base.level), updated=\(updated.level)"copy ← Settings(level: 0), copy.level ← 2
4func withLevel(_ nextLevel2: Int) -> Settings {5 var copy→ Settings(level: 0) = self6 copy.level→ 2 = nextLevel27 return copySettings(level: 2)8}updated ← Settings(level: 2), message ← base=0, updated=2
12let base = Settings(level: 0)13let updated→ Settings(level: 2) = baseSettings(level: 0).withLevel(selectedLevel2)14let message→ base=0, updated=2 = "base=\(base.level0), updated=\(updated.level2)"1516print(messagebase=0, updated=2)outputbase=0, updated=2
selectedLevel ← 1, base ← Settings(level: 0)
11let selectedLevel→ 1 = 112let base→ Settings(level: 0) = Settings(level: 0)13let updated = baseSettings(level: 0).withLevel(selectedLevel1)14let message = "base=\(base.level), updated=\(updated.level)"copy ← Settings(level: 0), copy.level ← 1
4func withLevel(_ nextLevel1: Int) -> Settings {5 var copy→ Settings(level: 0) = self6 copy.level→ 1 = nextLevel17 return copySettings(level: 1)8}updated ← Settings(level: 1), message ← base=0, updated=1
12let base = Settings(level: 0)13let updated→ Settings(level: 1) = baseSettings(level: 0).withLevel(selectedLevel1)14let message→ base=0, updated=1 = "base=\(base.level0), updated=\(updated.level1)"1516print(messagebase=0, updated=1)outputbase=0, updated=1
selectedLevel ← 4, base ← Settings(level: 0)
11let selectedLevel→ 4 = 412let base→ Settings(level: 0) = Settings(level: 0)13let updated = baseSettings(level: 0).withLevel(selectedLevel4)14let message = "base=\(base.level), updated=\(updated.level)"copy ← Settings(level: 0), copy.level ← 4
4func withLevel(_ nextLevel4: Int) -> Settings {5 var copy→ Settings(level: 0) = self6 copy.level→ 4 = nextLevel47 return copySettings(level: 4)8}updated ← Settings(level: 4), message ← base=0, updated=4
12let base = Settings(level: 0)13let updated→ Settings(level: 4) = baseSettings(level: 0).withLevel(selectedLevel4)14let message→ base=0, updated=4 = "base=\(base.level0), updated=\(updated.level4)"1516print(messagebase=0, updated=4)outputbase=0, updated=4
copied update
Returning a modified copy keeps the original value available for comparison.