Swift 5.6で強化された型システムについて


Type Placeholders

Swiftでは型推論を使用して、コードから冗長さを省くことができます。
しかし、コードを明確するために必要に応じて型を明示する際に、必要なのは型の特定の部分だけなのに、完全な型を指定しなければならないのは、面倒に感じることがあります。

enum Either<Left, Right> {
  case left(Left)
  case right(Right)
}

let either: Either<ClosedRange<Int>, Range<Int>> = .left(0...10)

新しい型プレースホルダー(正式にはプレースホルダー型)は、型アノテーションを部分的に記述し、必要な詳細のみを提供できます。
型プレースホルダーはアンダースコア記号_で記述され、不足な型情報は推論するようコンパイラに指示します。

enum Either<Left, Right> {
  case left(Left)
  case right(Right)
}

// Inferred as 'Either<ClosedRange<Int>, Range<Int>>'
let either: Either<_, Range<Int>> = .left(0...10)

Existential any

Swiftの実存型は、「特定のプロトコルに準拠した任意の型」の値を格納できます。
今日のところ、実存型はプレーンなプロトコル名またはプロトコル合成を使用して綴られます。

protocol DataSourceObserver { ... }

struct DataSource {
  var observers: [DataSourceObserver] { ... }
}

実存型は、その基礎となる型情報を消去します。
これは基礎となる型を動的に変更する必要がある場合に便利ですが、実存型がプロトコルに適合するような他の有用な機能を持つことを禁止しています。
既存の構文は、実存型がこれらの基本的な制限を持たない一般的な適合要件と同じように見えるため、混乱を招いています。

Swift 5.6では、実存型はanyキーワードで明示的にマークします。

protocol DataSourceObserver { ... }

struct DataSource {
  var observers: [any DataSourceObserver] { ... }
}