ProgrammingMobile Developer

Tell us about inout parameters in Swift: how they work, when to use them, and what pitfalls you might encounter?

Pass interviews with Hintsage AI assistant

Answer

The inout keyword in Swift allows a function to modify the value of the passed parameter directly (by reference), rather than working with a copy. This is analogous to pass-by-reference in some other languages.

Example:

func increment(_ value: inout Int) { value += 1 } var x = 10 increment(&x) // Now x == 11

Features and nuances:

  • Works only with variables (var), you cannot pass let.
  • The parameter is passed to the function by copy (copy-in), changes are made locally, and upon completion of the function, the result is copied back (copy-out).
  • You cannot pass the same argument to two inout parameters at the same time — this will result in a compilation error (conflicting access).

Tricky question

Question: Can you pass a property of a structure to a function with an inout parameter if the structure is being used as part of another object?

Answer: No, because Swift prohibits simultaneous access to the same property within a single statement (Exclusive Access to Memory) to avoid race conditions and undefined behavior. Example:

struct Point { var x: Int var y: Int } var p = Point(x: 1, y: 2) increment(&p.x) // ok increment(&p.y) // ok // increment(&p.x, &p.x) // will cause an error

Examples of real errors due to ignorance of the subtleties of the topic.


Story

In one project, a developer tried to pass the same variable simultaneously to two inout function parameters, which resulted in a compilation error. This forced a reconsideration of the function's architecture, breaking changes into two steps.


Story

An implementer was modifying an array via an inout parameter inside a loop, which led to unexpected results, as Swift copies the content upon passing, and changes were not synchronized between loops.


Story

A developer expected that inout parameters would always work "by reference", but encountered copy-in/copy-out semantics when working with classes and structures, which caused not all changes to be saved if nested objects of structures were modified.