はじめに
Swift 6.1と6.2に実装された主な仕様をまとめたので紹介します。
Swift 6.1 (Xcode 16.3)
SE-0439 Allow trailing comma in comma-separated lists
今まで配列や辞書でのみサポートされていた末尾のカンマが、関数の引数やタプルでも付けられるようになります。
let foo = (
foo,
bar,
baz, // !!!: 末尾にカンマを付けてビルドが通る
)
foo(
foo: 1,
bar: 1, // !!!: 末尾にカンマを付けてビルドが通る
)
プロジェクトでどうするかの方針も決めたほうがよさそうです。
- 積極的に末尾にカンマを付ける
- 積極的に末尾にカンマを付けない
- SwiftLintに任せる
- まだルールはなさそう
- 実装者の好みとする
参考リンク
SE-0441 Formalize ‘language mode’ terminology
「Swift version(Swift バージョン)」はツールチェーンのバージョンと「Language mode(言語モード)」の両方を指していて、曖昧な表現でした。
「Language mode」という用語を公式化し、言語モードを指すときに「Swift version」という用語を使わないようにします。
参考リンク
SE-0443 Precise Control Flags over Compiler Warnings
警告の出力方法を制御する、新しいコンパイラオプションが追加されます。
-
-Werror <group>
: 指定したグループ内の警告をエラーに昇格する -
-Wwarning <group>
: 指定したグループ内の警告を、抑制や昇格された場合でも警告のままにする
以前からあるコンパイラオプションは以下です。
-
-warnings-as-errors
: すべての警告をエラーに昇格する -
-no-warnings-as-errors
: 警告をエラーに昇格するのをキャンセルする -
-suppress-warnings
: すべての警告を抑制する
組み合わせた場合は後勝ちになります。
例:
-
-warnings-as-errors -Wwarning Deprecated
: 非推奨は警告のままだが、他の警告はエラーへ昇格する
参考リンク
SE-0444 Member import visibility
推移的なインポートにより呼び出すAPIのシグニチャが重複した場合、ビルドエラーが発生するようになります。
import Foo
を省略せず、APIのシグニチャが重複する場合は明示的にモジュール名を記述(例: Foo.bar()
)することで、問題なくビルドが通ると思います。
参考リンク
- https://github.com/swiftlang/swift-evolution/blob/main/proposals/0444-member-import-visibility.md
- https://www.hackingwithswift.com/swift/6.1/member-import-visiblity
SE-0445 Improving String.Index
's printed descriptions
String.Index
が CustomDebugStringConvertible
に適合します。
それにより、インデックスがいい感じにprintされるようになります。
let string = "👋🏼 Helló"
// Before
print(string.startIndex) // ⟹ Index(_rawBits: 15)
print(string.endIndex) // ⟹ Index(_rawBits: 983047)
// After
print(string.startIndex) // ⟹ 0[any]
print(string.endIndex) // ⟹ 15[utf8]
参考リンク
SE-0450 Package traits
Swift PackageにTraits(特性) を指定できるようになります。
let package = Package(
name: "Foo",
traits: [
.trait(
name: "FeatureFlags",
enabledTraits: [
"Foo",
"Bar",
],
),
],
)
特性が有効かどうかチェックすることで、条件付きコンパイルできます。
#if Foo
Button("Foo") {
print("Foo")
}
#else
EmptyView()
#endif
フィーチャーフラグを指定するのに役立ちます。
しかしコンパイル時に決定するので、ランタイム時にデバッグメニューなどから有効/無効を切り替えたいユースケースでは使えません。
参考リンク
- https://github.com/swiftlang/swift-evolution/blob/main/proposals/0450-swiftpm-package-traits.md
- https://speakerdeck.com/ikesyo/package-traits
参考リンク
- https://developer.apple.com/documentation/xcode-release-notes/xcode-16_3-release-notes
- https://x.com/SwiftLang/status/1906818682950692875
- https://www.swift.org/blog/swift-6.1-released/
- https://www.swift.org/swift-evolution/#?version=6.1
Swift 6.2 (Xcode 26.0)
SE-0446 Nonescapable Types
~Escapable
プロトコルが追加されます。
参考リンク
SE-0447 Span: Safe Access to Contiguous Storage
Span
はポインタ + 長さを表す型です。
連続した領域を確保する場合に使え、メモリを直接読みたい場合に Span
を使って切り出して読めます。
参考リンク
SE-0451 Raw identifiers
バックティック( `
)で括ることで、関数名やenumのケース名に様々な文字を含められます。
// Before
@Test("square returns x * x")
func squareIsXTimesX() {
#expect(square(4) == 4 * 4)
}
enum ColorVariant {
case _50
case _100
case _200
}
let color = Color(hue: .red, variant: ._100)
// After
@Test func `square returns x * x`() {
#expect(square(4) == 4 * 4)
}
enum ColorVariant {
case `50`
case `100`
case `200`
}
let color = Color(hue: .red, variant: .`100`)
プロジェクトでどうするかの方針も決めたほうがよさそうです。
- 積極的にバックティックを使う
- どうしても必要な場合のみバックティックを使う
- バックティックを使わない
- 実装者の好みとする
参考リンク
SE-0452 Integer Generic Parameters
整数を型パラメータとして渡せるようになります。
struct Matrix<let columns: Int, let rows: Int> {
var matrix: Vector<columns, Vector<rows, Double>>
}
参考リンク
SE-0453 InlineArray, a fixed-size array
固定サイズの配列を表す InlineArray
型が追加されます。
タプルと異なり、動的なインデックスでアクセスできます。
let elements: InlineArray<4, Int> = [1, 2, 3, 4]
for i in elements.indices {
foo(elements[i])
}
通常の Array
よりボトルネックが少ないです。
参考リンク
SE-0457 Expose attosecond representation of Duration
Duration
にアト秒を表すコンピューテッドプロパティ attoseconds
が追加されます。
init(attoseconds: Int128)
イニシャライザも追加されます。
参考リンク
SE-0458 Opt-in Strict Memory Safety Checking
オプトインの厳密なメモリ安全性チェックが追加されます。
-
-strict-memory-safety
フラグを付けてビルドすると有効になる -
@unsafe
を付けて、メモリの安全性が損われる可能性があることを示す -
@safe
を付けて、シグニチャに安全でない構造を含む宣言が、安全に使用できることを示す
参考リンク
SE-0459 Add Collection
conformances for enumerated()
enumerated()
の戻り値が Collection
に適合するようになります。
(1000..<2000).enumerated().dropFirst(500)
"abc".enumerated().reversed()
参考リンク
SE-0461 Run nonisolated async functions on the caller's actor by default
nonisolated
な async
関数が、呼び出し元のアクターで実行されるようになります。
参考リンク
SE-0469 Task Naming
Task
に人間が読みやすくするための名前を付けられるようになります。
let getUsers = Task("Get Users for \(accountID)") {
await users.get(accountID)
}
イニシャライザはiOS 13.0+で利用可能なため、すぐに使えます。
参考リンク
- https://github.com/swiftlang/swift-evolution/blob/main/proposals/0469-task-names.md
- https://developer.apple.com/documentation/swift/task/init(name:priority:operation:)-2dll5
SE-0470 Global-actor isolated conformances
分離適合性という、特定のグローバルアクターのみに適用が制限される適合性が追加されます。
// Before
@MainActor
final class MyModelType: Equatable {
var name: String
init(name: String) {
self.name = name
}
// error: main-actor-isolated static function '==' cannot satisfy non-isolated requirement 'Equatable.=='
static func ==(lhs: MyModelType, rhs: MyModelType) -> Bool {
lhs.name == rhs.name
}
}
// After
@MainActor
final class MyModelType: @MainActor Equatable {
var name: String
init(name: String) {
self.name = name
}
static func ==(lhs: MyModelType, rhs: MyModelType) -> Bool {
lhs.name == rhs.name
}
}
参考リンク
SE-0471 Improved Custom SerialExecutor isolation checking for Concurrency Runtime
以下のAPIはすべて「パスまたはクラッシュ」パターンに従います。
Actor/preconditionIsolated()
Actor/assumeIsolated(operation:)
SerialExecutor/checkIsolated()
クラッシュさせたくない場合を考慮し、 isIsolatingCurrentContext()
メソッドが追加されます。
checkIsolated()
は推奨のままですが、将来的に非推奨になる可能性があります。
参考リンク
SE-0472 Starting tasks synchronously from caller context
Task.immediate { ... }
を実行して、呼び出し元のコンテキストからタスクを同期的に実行できるようになります。
「immediate tasks(即時タスク)」と呼びます。
参考リンク
SE-0477 Default Value in String Interpolations
文字列補完にデフォルト値を指定できるようになります。
String?
型でも有用ですが、それ以外の型を扱う場合に特に便利です。
let age: Int? = nil
// Before
print("Your age: \(age.map { "\($0)" } ?? "missing")")
// After
print("Your age: \(age, default: "missing")")
参考リンク
SE-0480 Warning Control Settings for SwiftPM
SwiftPMで警告を制御する設定ができるようになります。
.target(
name: "MyLib",
swiftSettings: [
.treatAllWarnings(as: .error),
.treatWarning("DeprecatedDeclaration", as: .warning),
],
cSettings: [
.enableWarning("all"),
.disableWarning("unused-function"),
.treatAllWarnings(as: .error),
.treatWarning("unused-variable", as: .warning),
],
cxxSettings: [
.enableWarning("all"),
.disableWarning("unused-function"),
.treatAllWarnings(as: .error),
.treatWarning("unused-variable", as: .warning),
]
)
参考リンク
SE-0483 InlineArray
Type Sugar
InlineArray
にシンタックスシュガーが追加されます。
// Before
let fiveIntegers: InlineArray<5, Int> = .init(repeating: 99)
let fourIntegers: InlineAray<4, Int> = [1, 2, 3, 4]
// After
let fiveIntegers: [5 of Int] = .init(repeating: 99)
let fiveIntegers: [5 of _] = .init(repeating: 99)
let fourIntegers: [_ of _] = [1, 2, 3, 4]
参考リンク
SE-0486 Migration tooling for Swift features
Swiftの新仕様について、自動で修正するようになります。
参考リンク
参考リンク
おわりに
新仕様をまとめましたが、簡単に理解できない仕様の説明はざっくりとしか紹介していなかったりと、不十分な箇所があります。
正確な仕様の把握は一次ソースをご参照ください。
それでも、少しでもみなさんの理解に役立ったら嬉しいです