ProgramGuru

Initialization and valid starting state

Initialization and valid starting state

A student record should not begin with an impossible score. An initializer prepares a new instance and establishes the required properties. A failable initializer, written init?, can decline to construct an instance when input violates its contract.

What you’ll learn

  • Reject an invalid initial value with a failable initializer.
  • Explain why later mutation also needs an invariant policy.

Initialization and valid starting state in the example

  1. Validate input

    A student record should not begin with an impossible score.

    Validate input
  2. Initialize stored value

    Self names the instance being initialized, distinguishing its property from a same-named parameter.

    Initialize stored value
  3. Or return nil

    The first initializer succeeds and stores 80.

    Or return nil
The first initializer succeeds and stores 80. The second returns nil because 120 is outside the accepted range. Optional chaining reads a value only from the successfully created instance.

How initialization and valid starting state works

Self names the instance being initialized, distinguishing its property from a same-named parameter. Stored properties must reach valid initial values under Swift’s initialization rules. A class’s designated and convenience initializers have delegation rules, especially when inheritance is involved.

Work through initialization and valid starting state

Save this complete program as main.swift and run it with the Swift toolchain. No separate input file is needed.

Swift · complete program

struct Mark {
  let value: Int
  init?(_ value: Int) {
    guard (0...100).contains(value) else { return nil }
    self.value = value
  }
}
print(Mark(80)?.value ?? -1)
print(Mark(120) == nil)

Expected output

80
true

Follow the execution

The first initializer succeeds and stores 80. The second returns nil because 120 is outside the accepted range. Optional chaining reads a value only from the successfully created instance.

Try this program in the Swift compiler. Paste the complete source above.

Practice: Initialization and valid starting state

Your task: What should Mark(-5) return under this contract?

Swift · complete program

struct Mark {
  let value: Int
  init?(_ value: Int) {
    guard (0...100).contains(value) else { return nil }
    self.value = value
  }
}
print(Mark(80)?.value ?? -1)
print(Mark(120) == nil)

Worked answer

It returns nil because the allowed closed range begins at zero. The caller must handle failure rather than receiving a partially valid mark.

Protect validity after construction too

A valid initial value does not guarantee later mutations stay valid. Keep sensitive storage immutable or route updates through validated methods. Deinitialization concerns class lifetime and resource cleanup, which differs from constructing a valid starting value.

Check your decision

What should Mark(-5) return under this contract?
Choose one answer. You can try again.

Answer and explanation

It returns nil because the allowed closed range begins at zero.

It returns nil because the allowed closed range begins at zero. The caller must handle failure rather than receiving a partially valid mark.

Protect validity after construction too

It returns nil because the allowed closed range begins at zero. The caller must handle failure rather than receiving a partially valid mark. A valid initial value does not guarantee later mutations stay valid.

Further reading: official Swift language guide.

Reaching the recap and completing the quizzes are separate milestones.

    Next lesson: Inheritance, overrides and safe casting →