はじめに
これは、Xcode 8のRelease NotesでSwiftに関係する部分を読んだときのメモです。
あくまでも個人的なメモですので、内容の正確性についてはあまり期待しないでください。
swift-evolutionに元ネタがある項目については、そちらを見た方が理解しやすいでしょう。たぶん。
情報を確認した環境
環境 | 情報 |
---|---|
Xcode | 8.0 (8A218a) |
iOS | 10.0 |
Swift | 3.0 |
Date | 2016/9/23 |
Release Notes - Swift
(25680392) Swift 2.3はSwift 2.2とは似てるけど違います
Xcode 8で使えるSwift 2(2.3)はXcode 7.3.1のSwift 2とよく似てます。けど、これは新しいSDKのために更新されてます。Xcode 7.3.1でコンパイルされたフレームワークとの互換性はありません。
マイグレーション
Swift 2からSwift 3へのマイグレーションについては、Swift Migration Guideを参照して下さい。
Swift.org - Migrating to Swift 2.3 or Swift 3 from Swift 2.2
https://swift.org/migration-guide/
(26919123) エラーメッセージが詳しくなりました
Swiftのプログラムが実行時にnull例外で止まったとき、エラーメッセージで『!』や暗黙的開示オプショナル型の使われているソースコードの位置を報告するようになりました。
※Xcode 7.3.1から見ると、変わってない?
(SE-0111) 関数の型の一部として関数の引数ラベルを考慮していた仕様を廃止して、型システムをシンプルに
Swiftの関数の型から引数ラベルを取り除きます。その代わり、関数の名前やサブスクリプトやイニシャライザの名前の一部になります。
関数やサブスクリプトやイニシャライザを呼び出すときは、今までと同じで引数ラベルが必要です。
func doSomething(x: Int, y: Int) {}
doSomething(x: 0, y: 0) // 引数ラベルが必要
しかし、関数やイニシャライザへの参照は引数ラベルを使わなくなります。
let f = doSomething(x:y:) // 推測される型は『(Int, Int) -> Void』になります
付け加えると、明示的に記述された関数型も引数ラベルを使わなくなります。それでも、文書化のために引数ラベルを使いたい場合、引数ラベルの位置に『_』を使ってください。
typealias CompletionHandler =
(token: Token, error: Error?) -> Void // エラー:関数型は引数ラベルを持てないのでエラー
typealias CompletionHandler =
(_ token: Token, _ error: Error?) -> Void // ok: 名前は文書化のために使われる
swift-evolution/0111-remove-arg-label-type-significance.md at master · apple/swift-evolution · GitHub
https://github.com/apple/swift-evolution/blob/master/proposals/0111-remove-arg-label-type-significance.md
(SE-0116) Objective-CのidがSwiftでAnyObjectになっていたのをAnyに変更
Objective-CのAPIでidが使われていた箇所が、SwiftではAnyObjectじゃなくてAnyになるように変わりました。同様に、型の指定されていないNSArrayやNSDictionaryは、Swiftでは[Any]や[AnyHashable: Any]になります。
swift-evolution/0116-id-as-any.md at master · apple/swift-evolution · GitHub
https://github.com/apple/swift-evolution/blob/master/proposals/0116-id-as-any.md
(27853737) IBActionのsenderにAnyが指定できるようになりました
(27639935) idがAnyになったため、AnyObjectを使っていた部分がエラーになる事があります
Objective-Cのidとして、SwiftではAnyObjectではなくAnyが使われるようになったため、AnyObjectで動的なルックアップを使っていた部分がエラーになる事があります。
例えばこんな感じです。
guard let fileEnumerator = FileManager.default.enumerator(atPath: path) else {
return
}
for fileName in fileEnumerator {
if fileName.hasSuffix(".txt") { // エラー: Any型のElementはhasSuffix()を持ってない
print(fileName)
}
}
修正する方法としては、動的なルックアップの前にAnyObjectにキャストするか、もしくは目的の型にキャストします。
guard let fileEnumerator = FileManager.default.enumerator(atPath: path) else {
return
}
for fileName in fileEnumerator {
if (fileName as AnyObject).hasSuffix(".txt") { // AnyObjectにキャスト
print(fileName)
}
}
(SE-0103) @noescapeの動作がデフォルトになりました
クロージャーの引数は@noescapeの動作がデフォルトになりました。@escapingを使うことで、クロージャーが脱出できるようになります。
『@autoclosure(escaping)』と書いていたところは『@autoclosure @escaping』と書くことになりました。アノテーションとしての@noescapeと@autoclosure(escaping)は廃止されました。
swift-evolution/0103-make-noescape-default.md at master · apple/swift-evolution · GitHub
https://github.com/apple/swift-evolution/blob/master/proposals/0103-make-noescape-default.md
(SE-0102) @noreturn属性が廃止されて、代わりに列挙型のNeverを戻り値として指定するようになりました
呼び出し元に制御を戻さない時に使っていた、@noreturn属性は削除されました。代わりに Never を戻り値の型として指示します。
@noreturn func fatalError(msg: String) { ... } // old
func fatalError(msg: String) -> Never { ... } // new
func performOperation<T>(continuation: @noreturn T -> ()) { ... } // old
func performOperation<T>(continuation: T -> Never) { ... } // new
(15101588) Objective-Cでプロトコル修飾されたクラスがSwiftではプロトコル型の値になります(?)
Xcode imports Objective-C protocol-qualified classes (for example Class <NSCoding>) into Swift as protocol type values (NSCoding.Type).
Objective-Cでプロトコル修飾されたクラスを、Swiftではプロトコル型の値としてインポートします。例えば、『Class <NSCoding>』が『NSCoding.Type』になります(?)
※要確認
(SE-0055) nullになる可能性のあるUnsafePointerは、オプショナルを使うようになりました
UnsafePointer, UnsafeMutablePointer, AutoreleasingUnsafeMutablePointer, OpaquePointer, Selector, NSZoneなどの型は通常の型になりました。これらは決してnilになることはありません。
nullになる可能性のあるポインターは、Swiftではオプショナル型になりました。例えば『UnsafePointer?』といった感じです。
Cから取りこまれるオブジェクト以外の型(int*など)についても考慮済みです。
_NonnullやNS_ASSUME_NONNULL_BEGIN/_ENDブロックで指定されているポインターは通常のポインター型になります。例えば『NSInteger * _Nonnull』は『UnsafeMutablePointer』になります
_Nullableが指定されているポインターはオプショナル型になります。例えば『NSInteger * _Nullable』は『UnsafeMutablePointer?』になります
_Null_unspecifiedが指定されていたり、NS_ASSUME_NONNULL_BEGIN/_ENDの外にある指定の無いポインターは暗黙的開示オプショナル型になります。例えば『NSInteger * _Null_unspecified』は『UnsafeMutablePointer!』になります
これは、Swift標準ライブラリーと一致するように調整されています。
Cの可変長引数を取る関数への、nullになる可能性のあるポインターを渡すのは難しいです(?) Swiftではこれは直接には許可されていません。この問題を回避するためには、次のようにして、ポインターと同じサイズの整数値を渡してください。
Int(bitPattern: nullablePointer)
インポートしたポインターが指示する型は、注釈がついていても、常に_Nullableであるとは想定されません(?) しかしながら、暗黙的もしくは明示的に_Null_unspecifiedを指定した場合、オプショナル型としてインポートされます。
swift-evolution/0055-optional-unsafe-pointers.md at master · apple/swift-evolution · GitHub
https://github.com/apple/swift-evolution/blob/master/proposals/0055-optional-unsafe-pointers.md
(16888940) Core Foundationの型名から、末尾の『Ref』を削除しました
Core Foundationの型名から、末尾の『Ref』を削除しました。『CFStringRef』の場合、『CFString』になります。ただし、『Ref』付きと『Ref』無しの両方の名前が両方使われている場合は例外で、『Ref』付きのままでインポートされます。
(SE-0099) 条件句で標準的なシンタックスを使うようになりました
if, guard, whileの条件句の書式で、より標準的なシンタックスを使えるように修正しました。それぞれのパターンやオプショナルバインディングにcaseかletを付けて、区切りは全て『,』になります。
以前の書き方。
if let a = a, b = b where a == b {}
新しい書き方。
if let a = a, let b = b, a == b {}
※Xcode 8.0ではソースコードの修飾が間に合ってない?
swift-evolution/0099-conditionclauses.md at master · apple/swift-evolution · GitHub
https://github.com/apple/swift-evolution/blob/master/proposals/0099-conditionclauses.md
(22051279) ネストしたジェネリクス関数が、周囲の環境をキャプチャ出来るようになりました
こんな感じです。
func outer<T>(t: T) -> T {
func inner<U>(u: U) -> (T, U) {
return (t, u)
}
return inner(u: (t, t)).0
}
(SE-0046) 関数の引数は、全ての引数でラベル付けされるようになりました
関数の引数は、全ての引数でラベル付けされるようになりました。この変更で、最初の引数も2個目以降の引数と同じように振る舞う事になりました。
以前の書き方。
func foo(x: Int, y: Int) {}
foo(1, y: 2)
func bar(a a: Int, b: Int) {}
bar(a: 3, b: 4)
新しい書き方。
func foo(_ x: Int, y: Int) {}
foo(1, y: 2)
func bar(a: Int, b: Int) {}
bar(a: 3, b: 4)
swift-evolution/0046-first-label.md at master · apple/swift-evolution · GitHub
https://github.com/apple/swift-evolution/blob/master/proposals/0046-first-label.md
(SE-0064) Objective-Cのゲッターやセッターへのセレクターが#selectorで書けるようになりました
Objective-Cのゲッターやセッターへのセレクターが#selectorで書けるようになりました。
こんな感じです。
let sel1 = #selector(getter: UIView.backgroundColor) // sel1 has type Selector
let sel2 = #selector(setter: UIView.backgroundColor) // sel2 has type Selector
swift-evolution/0064-property-selectors.md at master · apple/swift-evolution · GitHub
https://github.com/apple/swift-evolution/blob/master/proposals/0064-property-selectors.md
コレクションのサブタイプ変換やダイナミックキャストが、プロトコルでも動作するようになりました
こんな感じです。
protocol P {}
extension Int: P {}
var x: [Int] = [1, 2, 3]
var p: [P] = x
var x2 = p as! [Int]
※うまく使うと便利そう?
(SR-2131) 空の文字列が全ての文字列の接頭辞・接尾辞と一致するようになりました
hasPrefixとhasSuffix関数で空の文字列を渡したとき、全ての文字列の接頭辞・接尾辞と一致するようになりました。
NS_OPTIONSのNoneは使用不可になりました
NS_OPTIONSのNoneは、インポートする時点で使用不可としてマークされます。Noneの代わりに『[]』を使うことで、空のオプションセットを作ることが出来ます。
※要確認
typealiasesでジェネリクスが使えるようになりました
typealiasesでジェネリクスが使えるようになりました。
こんな感じです。
typealias StringDictionary<T> = Dictionary<String, T>
typealias IntFunction<T> = (T) -> Int
typealias MatchingTriple<T> = (T, T, T)
typealias BackwardTriple<T1, T2, T3> = (T3, T2, T1)
@noescapeはより一般的な属性として拡張されました
@noescapeはより一般的な属性として拡張されました。@noescape関数型の値を宣言できます。また、ローカル変数を@noescape型にしたり、typealiasesで@noescapeを使ったり出来ます。
こんな感じです。
func apply<T, U>(@noescape f: T -> U,
@noescape g: (@noescape T -> U) -> U) -> U {
return g(f)
}
関数のカリー化に関する構文は削除されました
ジェネリクスで指定できる要素として、スーパークラスを指定できるようになりました。
func f<Food : Chunks<Meat>, Meat : Molerat>(f: Food, m: Meat) {}
rethrowsの指定された関数で、catchブロックの中から例外を発生させることが出来るようになりました。
func process(f: () throws -> Int) rethrows -> Int {
do {
return try f()
} catch is SomeError {
throw OtherError()
}
}
※未確認
rethrowsの指定された関数で、例外を投げる可能性があるオプショナルなクロージャーを実行することが出来るようになりました。
func executeClosureIfNotNil(closure: (() throws -> Void)?) rethrows {
try closure?()
}
※未確認
(SE-0067) FloatingPointを拡張して、IEEE 754に必要な操作を満たすように修正しました
FloatingPointを拡張して、IEEE 754に必要な操作を満たすように修正しました。また、いくつか役に立つプロパティが追加されました。変更のほとんどは追加になっていますが、既存のコードに影響を与える変更が4つあります。
- FloatingPoint型の『%』は無効になりました。formTruncatingRemainder(dividingBy:)が代わりに使えます。
- 『.NaN』は『.nan』に変更になりました
- 『.quietNaN』は削除されました。代わりに『.nan』を使います
- 『isSignaling』は『isSignalingNaN』に変更になりました
swift-evolution/0067-floating-point-protocols.md at master · apple/swift-evolution · GitHub
https://github.com/apple/swift-evolution/blob/master/proposals/0067-floating-point-protocols.md
(SE-0071)ほとんどのキーワードが、メンバーとして使用できるようになりました
ほとんどのキーワードが、メンバーとして使用できるようになりました。いちいち『`』で前後を囲わなくても、そのまま使えます。
let cell = UITableViewCell(style: .default, reuseIdentifier: nil)
particleSystem.imageSequenceAnimationMode = SCNParticleImageSequenceAnimationMode.repeat
swift-evolution/0071-member-keywords.md at master · apple/swift-evolution · GitHub
https://github.com/apple/swift-evolution/blob/master/proposals/0071-member-keywords.md
(SE-0062) キーパスの指定に『#keyPath』が使えるようになりました
person.valueForKeyPath(#keyPath(Person.bestFriend.lastName))
swift-evolution/0062-objc-keypaths.md at master · apple/swift-evolution · GitHub
https://github.com/apple/swift-evolution/blob/master/proposals/0062-objc-keypaths.md
(SE-0031) inoutが『:』の後ろになりました
以前の書き方。
func foo(inout x: Int) {
}
新しい書き方。
func foo(x: inout Int) {
}
swift-evolution/0031-adjusting-inout-declarations.md at master · apple/swift-evolution · GitHub
https://github.com/apple/swift-evolution/blob/master/proposals/0031-adjusting-inout-declarations.md
(SE-0034) 『#line』が『#sourceLocation』になりました
swift-evolution/0034-disambiguating-line.md at master · apple/swift-evolution · GitHub
https://github.com/apple/swift-evolution/blob/master/proposals/0034-disambiguating-line.md
(SE-0025) privateでマークされた宣言は、そのスコープの中でだけ使えるようになりました
元々の『private』は『fileprivate』になりました。
swift-evolution/0025-scoped-access-level.md at master · apple/swift-evolution · GitHub
https://github.com/apple/swift-evolution/blob/master/proposals/0025-scoped-access-level.md
(SE-0036) 列挙型の要素には『.』が必要です
列挙型の要素にインスタンスメンバーからアクセスした場合、現在はコンパイルエラーになります。
enum Color {
case red, green, blue
func combine(with color: Color) -> Color {
// return red // コンパイルエラー
return .red // 使用可能
}
}
swift-evolution/0036-enum-dot.md at master · apple/swift-evolution · GitHub
https://github.com/apple/swift-evolution/blob/master/proposals/0036-enum-dot.md
(SE-0043) case句で複数のパターンで変数を宣言できるようになりました
swift-evolution/0043-declare-variables-in-case-labels-with-multiple-patterns.md at master · apple/swift-evolution · GitHub
https://github.com/apple/swift-evolution/blob/master/proposals/0043-declare-variables-in-case-labels-with-multiple-patterns.md
(17960407) 親クラスや派生クラスがジェネリクスでも、イニシャライザが継承されます
class Base<T> {
let t: T
init(t: T) {
self.t = t
}
}
class Derived<T> : Base<T> {
// init(t: T) is now synthesized to call super.init(t: t)
}
(SE-0081) where句はシグネチャのあと、本文の前に書くようになりました
以前の書き方。
func anyCommonElements<T : SequenceType, U : SequenceType
where T.Generator.Element: Equatable, T.Generator.Element == U.Generator.Element>
(lhs: T, _ rhs: U) -> Bool
{
...
}
新しい書き方。
func anyCommonElements<T : SequenceType, U : SequenceType>(lhs: T, _ rhs: U) -> Bool
where T.Generator.Element: Equatable, T.Generator.Element == U.Generator.Element
{
...
}
古い書き方も今のところ許されていますが、そのうち却下されます。
swift-evolution/0081-move-where-expression.md at master · apple/swift-evolution · GitHub
https://github.com/apple/swift-evolution/blob/master/proposals/0081-move-where-expression.md
(SE-0112) NSErrorはErrorにブリッジされるようになりました
Objective-CのNSErrorは、SwiftではErrorプロトコルにブリッジされます。NSStringがStringにブリッジされるのと同じような感じです。
UIApplicationDelegateのapplication(_:didFailToRegisterForRemoteNotificationsWithError:)はこんな感じでした。
optional func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: NSError)
この場合、引数がErrorになります。
optional func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error)
また、CocoaやCocoa Touchからインポートしたエラー型は全ての情報を持っているので、わざわざNSErrorとしてキャッチする必要は無くなりました。
例えば、ユーザー情報を取得するにはこんな感じになります。
catch let error as CocoaError where error.code == .fileReadNoSuchFileError {
print("No such file: \(error.url)")
}
Swiftで定義されたエラー型は、新しいLocalizedErrorプロトコルを使うことで、ローカライズ済みの説明を提供することが出来ます。
extension HomeworkError : LocalizedError {
var errorDescription: String? {
switch self {
case .forgotten: return NSLocalizedString("I forgot it")
case .lost: return NSLocalizedString("I lost it”)
case .dogAteIt: return NSLocalizedString("The dog ate it”)
} }
}
同様に、新しいRecoverableErrorやCustomNSErrorプロトコルを使うことで、さらなる制御が可能になります。
swift-evolution/0112-nserror-bridging.md at master · apple/swift-evolution · GitHub
https://github.com/apple/swift-evolution/blob/master/proposals/0112-nserror-bridging.md
(SE-0095) プロトコル合成が変わりました
『protocol<...>』の書式が削除になり、代わりに『&』を使うようになりました。
let a: Foo & Bar
let b = value as? A & B & C
func foo<T : Foo & Bar>(x: T) { … }
func bar(x: Foo & Bar) { … }
typealias G = GenericStruct<Foo & Bar>
以前は、空のプロトコル合成は『protocol<>』を使っていました。これも削除されて、代わりに『Any』を使うことになりました。
swift-evolution/0095-any-as-existential.md at master · apple/swift-evolution · GitHub
https://github.com/apple/swift-evolution/blob/master/proposals/0095-any-as-existential.md
(SE-0072) 暗黙的なブリッジ変換は無くなりました
Swiftの値型から対応するObjective-Cのオブジェに変換する場合、『as』を使用します。例えば『string as NSString』といった感じです。
Any Swift value can also be converted to its boxed id representation with as AnyObject
Swiftの値は『as AnyObject』で、idにBox化出来ます(?)
swift-evolution/0072-eliminate-implicit-bridging-conversions.md at master · apple/swift-evolution · GitHub
https://github.com/apple/swift-evolution/blob/master/proposals/0072-eliminate-implicit-bridging-conversions.md
(SE-0040) 属性の引数指定は『=』ではなく『:』を使うようになりました
@available(*, unavailable, renamed: "MyRenamedProtocol")
typealias MyProtocol = MyRenamedProtocol
@warn_unused_result(mutable_variant: "sortInPlace")
public func sort() -> [Self.Generator.Element]
@available(*, deprecated, message: "it will be removed in Swift 3. Use the 'generate()' method on the collection.")
public init(_ bounds: Range<Element>)
swift-evolution/0040-attributecolons.md at master · apple/swift-evolution · GitHub
https://github.com/apple/swift-evolution/blob/master/proposals/0040-attributecolons.md
(SE-0096) .dynamicTypeプロパティがtype(of:)関数に変わりました
『dynamicType』は削除になりました。代わりに『type(of:)』関数が追加になりました。既存のコードで『.dynamicType』を使っている部分は、新しい書き方にする必要があります。sizeofと一緒に『.dynamicType』を使っているコードは、SE-0101で導入されたMemoryLayoutを使う形に変更する必要があります。
※要確認
swift-evolution/0096-dynamictype.md at master · apple/swift-evolution · GitHub
https://github.com/apple/swift-evolution/blob/master/proposals/0096-dynamictype.md
(SE-0077) 演算子の宣言が改良されました
新しい演算子を追加するための構文が大幅に変更されました。新しいモデルはマジックナンバーを使った物では無く、優先グループを元にした物になっています。これは新しい演算子の宣言にだけ影響して、既存の演算子オーバーロードを追加することはありません。
※要確認
swift-evolution/0077-operator-precedence.md at master · apple/swift-evolution · GitHub
https://github.com/apple/swift-evolution/blob/master/proposals/0077-operator-precedence.md
(SE-0115) 『*LiteralConvertible』が『ExpressibleBy*Literal』に変更になりました
役割を明確にするために『*LiteralConvertible』が『ExpressibleBy*Literal』に変更になりました。これらのプロトコルの要件は変更になってません。
swift-evolution/0115-literal-syntax-protocols.md at master · apple/swift-evolution · GitHub
https://github.com/apple/swift-evolution/blob/master/proposals/0115-literal-syntax-protocols.md
(SE-0060) デフォルト値をもつ引数は、宣言順に指定する必要があります
デフォルト値をもつ引数は、宣言順に指定する必要があります。関数を呼び出す側は、常に宣言された順番で引数を指定します。
func requiredArguments(a: Int, b: Int, c: Int) {}
func defaultArguments(a: Int = 0, b: Int = 0, c: Int = 0) {}
requiredArguments(a: 0, b: 1, c: 2)
requiredArguments(b: 0, a: 1, c: 2) // error
defaultArguments(a: 0, b: 1, c: 2)
defaultArguments(b: 0, a: 1, c: 2) // error
デフォルト値をもつ引数は、順番を守っている限り、省くことが出来ます。
defaultArguments(a: 0) // ok
defaultArguments(b: 1) // ok
defaultArguments(c: 2) // ok
defaultArguments(a: 1, c: 2) // ok
defaultArguments(b: 1, c: 2) // ok
defaultArguments(c: 1, b: 2) // error
swift-evolution/0060-defaulted-parameter-order.md at master · apple/swift-evolution · GitHub
https://github.com/apple/swift-evolution/blob/master/proposals/0060-defaulted-parameter-order.md
(SE-0053) 無駄なletは削除されました
関数の引数にあるletは、宣言から取り除かれます。
コンパイルエラーになる形。
func foo(let x: Int) { ... }
好まれる形。
func foo(x: Int) { ... }
swift-evolution/0053-remove-let-from-function-parameters.md at master · apple/swift-evolution · GitHub
https://github.com/apple/swift-evolution/blob/master/proposals/0053-remove-let-from-function-parameters.md
(SE-0003) 関数の引数でvarは使えなくなりました
関数の引数でvarは使えなくなりました。
以前の書き方。
func foo(var x: Int) {
}
新しい書き方。
func foo(x: Int) {
var x = x
}
swift-evolution/0003-remove-var-parameters.md at master · apple/swift-evolution · GitHub
https://github.com/apple/swift-evolution/blob/master/proposals/0003-remove-var-parameters.md
(SE-0117) publicなクラスはモジュールの外でサブクラス化出来なくなりました
publicなクラスはモジュールの外でサブクラス化出来なくなりました。publicなメソッドはモジュールの外でオーバーライドできなくなりました。モジュールの外でサブクラス化したりオーバーライドしたりする場合、openで宣言してください。これは、publicを超える新しいアクセスレベルです。
Objective-Cからインポートしたクラスやメソッドは、publicでは無くopenになります。ユニットテストで@testableを使ってインポートした場合は、publicでもサブクラス化やオーバーライドが可能です。
swift-evolution/0117-non-public-subclassable-by-default.md at master · apple/swift-evolution · GitHub
https://github.com/apple/swift-evolution/blob/master/proposals/0117-non-public-subclassable-by-default.md
(SR-700) Swiftからエラーが投げられたとき、NSErrorのdomainプロパティにはモジュールの名前や定数が含まれています
※要確認
(25759260) 『init』で名前が始まるメソッドは、Objective-Cのinitメソッドの仲間として、考慮される(?)
Methods whose names start with init are no longer considered to be part of the Objective-C "init" method family.
※要確認
(SE-0093) スライス型は、元のコレクションにアクセスするためのbaseプロパティを持ちます
swift-evolution/0093-slice-base.md at master · apple/swift-evolution · GitHub
https://github.com/apple/swift-evolution/blob/master/proposals/0093-slice-base.md
(26561852) プレイグラウンドのファイルリテラルはNSURLではなくURLになりました
(SE-0136 and SE-0101) メモリーレイアウト関係の変更いろいろ
sizeof(), strideof(), alignof()関数が削除されました。代わりに、MemoryLayout.size, MemoryLayout.stride, MemoryLayout.alignmentが使えます。
sizeofValue(), strideofValue(), alignofValue()はMemoryLayout.size(ofValue:), MemoryLayout.stride(ofValue:), and MemoryLayout.alignment(ofValue:)に変更になりました。
// Swift 2.3:
var p = Person()
sizeofValue(p) // 40
sizeof(Double.self) // 8
alignof(Double.self) // 8
// Swift 3.0:
var p = Person()
MemoryLayout.size(ofValue: p) // 40
MemoryLayout<Double>.size // 8
MemoryLayout<Double>.alignment // 8
swift-evolution/0101-standardizing-sizeof-naming.md at master · apple/swift-evolution · GitHub
https://github.com/apple/swift-evolution/blob/master/proposals/0101-standardizing-sizeof-naming.md
swift-evolution/0136-memory-layout-of-values.md at master · apple/swift-evolution · GitHub
https://github.com/apple/swift-evolution/blob/master/proposals/0136-memory-layout-of-values.md
(SE-0130) Stringのイニシャライザやappendが使いやすくなりました
CharacterとUnicodeScalarの繰り返しを指定するStringのイニシャライザとString.appendは、引数から型が特定されるようになりました。
以前の書き方。
let s1 = String(repeating: "x" as Character, count: 10)
let s2 = String(repeating: "y" as UnicodeScalar, count: 10)
新しいシンプルな書き方。
let s1 = String(repeating: "x", count: 10)
let s2 = String(repeating: "y", count: 10)
これも、以前の書き方。
s1.append("x" as UnicodeScalar)
新しいシンプルな書き方。
s1.append("x")
こんな書き方も出来ます。
s1.append(String(UnicodeScalar("x")))
swift-evolution/0130-string-initializers-cleanup.md at master · apple/swift-evolution · GitHub
https://github.com/apple/swift-evolution/blob/master/proposals/0130-string-initializers-cleanup.md
(SE-0125) 複数参照を確認する方法が変わりました
isUniquelyReferenced()とisUniquelyReferencedNonObjC()は削除されました。代わりに、isKnownUniquelyReferenced()を使います。isUniquelyReferenced()を使う際に必要だった、NonObjectiveCBaseも削除されました。
ManagedBufferPointer.holdsUniqueReferenceはManagedBufferPointer.isUniqueReferenceに変更になりました。
以前の書き方。
class SwiftKlazz : NonObjectiveCBase {}
expectTrue(isUniquelyReferenced(SwiftKlazz()))
var managedPtr : ManagedBufferPointer = ...
if !managedPtr.holdsUniqueReference() {
print("not unique")
}
新しい書き方。
class SwiftKlazz {}
expectTrue(isKnownUniquelyReferenced(SwiftKlazz()))
var managedPtr : ManagedBufferPointer = ...
if !managedPtr.isUniqueReference() {
print("not unique")
}
swift-evolution/0125-remove-nonobjectivecbase.md at master · apple/swift-evolution · GitHub
https://github.com/apple/swift-evolution/blob/master/proposals/0125-remove-nonobjectivecbase.md
(SE-0107) Unsafe[Mutable]RawPointerが追加になりました
Unsafe[Mutable]RawPointerが追加になりました。これは、Unsafe[Mutable]Pointerを置き換える物です。UnsafePointerからUnsafePointerへの変換は許可されません。
Unsafe[Mutable]RawPointerは型指定の無いメモリアクセスやメモリへの型付けを提供します(?) 型付けされたメモリは、安全にポインター型に変換できます。詳しくは、bindMemory(to:capacity:), assumingMemoryBound(to:), withMemoryRebound(to:capacity:)を見てください。
swift-evolution/0107-unsaferawpointer.md at master · apple/swift-evolution · GitHub
https://github.com/apple/swift-evolution/blob/master/proposals/0107-unsaferawpointer.md
(SE-0128) UnicodeScalarのイニシャライザが失敗するようになりました
UnicodeScalarのイニシャライザが、失敗可能な物に変わりました。
以前の書き方。
var string = ""
let codepoint: UInt32 = 55357 // this is invalid
let ucode = UnicodeScalar(codepoint) // Program crashes at this point.
string.append(ucode)
新しい書き方。
var string = ""
let codepoint: UInt32 = 55357 // this is invalid
if let ucode = UnicodeScalar(codepoint) {
string.append(ucode)
} else {
// do something else
}
swift-evolution/0128-unicodescalar-failable-initializer.md at master · apple/swift-evolution · GitHub
https://github.com/apple/swift-evolution/blob/master/proposals/0128-unicodescalar-failable-initializer.md
(SE-0127) ポインター周りの変更いろいろ
withUnsafePointerとwithUnsafeMutablePointer関数に、『to:』引数が追加されました。これらの関数を使うときは、この引数が必須です。
withUnsafePointersとwithUnsafeMutablePointersは削除になりました。これらの関数の代わりに、1つのポインターを使う関数を使ってください。
unsafeAddressOf関数は削除になりました。代わりに、ObjectIdentifier(x).unsafeAddressを使います。
ManagedProtoBufferクラスは削除になりました。型への明示的な参照として使うクラスは、ManagedBufferになりました。
swift-evolution/0127-cleaning-up-stdlib-ptr-buffer.md at master · apple/swift-evolution · GitHub
https://github.com/apple/swift-evolution/blob/master/proposals/0127-cleaning-up-stdlib-ptr-buffer.md
(SE-0131) ハッシュを使うコレクションはAnyHashableを使います
標準ライブラリで、ハッシュを使うコレクションのためにAnyHashableが導入されました。Objective-CのNSDictionaryやNSSetをインポートしたとき、[AnyHashable: Any]やSetになります。
swift-evolution/0131-anyhashable.md at master · apple/swift-evolution · GitHub
https://github.com/apple/swift-evolution/blob/master/proposals/0131-anyhashable.md
(SE-0124) IntとUIntのイニシャライザが変わりました
Int.init(ObjectIdentifier)とUInt.init(ObjectIdentifier)は『bitPattern:』ラベルが必要になりました。それらのイニシャライザはObjectIdentifierを引数に取ります。
以前の書き方。
let x: ObjectIdentifier = ...
let u = UInt(x)
let i = Int(x)
新しい書き方。
let x: ObjectIdentifier = ...
let u = UInt(bitPattern: x)
let i = Int(bitPattern: x)
swift-evolution/0124-bitpattern-label-for-int-initializer-objectidentfier.md at master · apple/swift-evolution · GitHub
https://github.com/apple/swift-evolution/blob/master/proposals/0124-bitpattern-label-for-int-initializer-objectidentfier.md
(SE-0109) Booleanプロトコルは削除されました
swift-evolution/0109-remove-boolean.md at master · apple/swift-evolution · GitHub
https://github.com/apple/swift-evolution/blob/master/proposals/0109-remove-boolean.md
(SE-0113) FloatingPointに関数が追加されました
FloatingPointに関数が追加になりました。
func rounded(_ rule: FloatingPointRoundingRule) -> Self
mutating func round( _ rule: FloatingPointRoundingRule)
これらのメソッドは、IEEE 754のroundToIntegralに接続されます。同様に、C / C++のround(), ceil(), floor(), trunc()も提供されます。
他にも、fabs, sqrt, fma, remainder, fmod, ceil, floor, round, truncがFloatingPointで使えるように作業中です(?)
swift-evolution/0067-floating-point-protocols.md at master · apple/swift-evolution · GitHub
https://github.com/apple/swift-evolution/blob/master/proposals/0067-floating-point-protocols.md
swift-evolution/0113-rounding-functions-on-floatingpoint.md at master · apple/swift-evolution · GitHub
https://github.com/apple/swift-evolution/blob/master/proposals/0113-rounding-functions-on-floatingpoint.md
(SE-0091) 型やエクステンションの中で、演算子が定義できるようになりました
struct Foo: Equatable {
let value: Int
static func ==(lhs: Foo, rhs: Foo) -> Bool {
return lhs.value == rhs.value
}
}
これらの演算子はstaticで宣言して、グローバルの物と同じシグネチャを持つ必要があります。
この変更によって、プロトコルで宣言する演算子もstaticにする事になりました。
protocol Equatable {
static func ==(lhs: Self, rhs: Self) -> Bool
}
注釈:SE-0091に記載されている型チェックの最適化はまだ実装されていません
swift-evolution/0091-improving-operators-in-protocols.md at master · apple/swift-evolution · GitHub
https://github.com/apple/swift-evolution/blob/master/proposals/0091-improving-operators-in-protocols.md
(SE-0120) partitionメソッドの改訂
コレクションのpartition()とpartition(isOrderedBefore:)は削除されました。それらは、partition(by:)に置き換えられます。
以前の書き方。
let p = c.partition()
新しい書き方。
let p = c.first.flatMap({ first in
c.partition(by: { $0 >= first })
}) ?? c.startIndex
swift-evolution/0120-revise-partition-method.md at master · apple/swift-evolution · GitHub
https://github.com/apple/swift-evolution/blob/master/proposals/0120-revise-partition-method.md
(SE-0133) flattenがjoinedになりました
Sequence.flatten()とCollection.flatten()は、それぞれ、Sequence.joined()とCollection.joined()に変更されました。
Swift 2.3での書き方。
[[1,2],[3]].flatten()
Swift 3.0での書き方。
[[1,2],[3]].joined() // [1,2,3]
[[1,2],[3]].joined(separator: []) // [1,2,3]
[[1,2],[3]].joined(separator: [0]) // [1,2,0,3]
swift-evolution/0133-rename-flatten-to-joined.md at master · apple/swift-evolution · GitHub
https://github.com/apple/swift-evolution/blob/master/proposals/0133-rename-flatten-to-joined.md
(22457329) アクティブコンパイル条件とは
アクティブコンパイル条件は、ビルド設定をSwiftコンパイラーに渡すための新しい設定です。この設定のそれぞれの要素は、『-D』付きでswiftcに渡され、プリプロセッサマクロと同じようにclangに渡されます(?)
(24213154) Swiftコンパイラーのオプション追加
Swiftコンパイラーのオプションに、新しい設定が2つ追加されました。
- -suppress-warnings (SWIFT_SUPPRESS_WARNINGS)
- -warnings-as-errors (SWIFT_TREAT_WARNINGS_AS_ERRORS)
これらの設定は、clangのビルド設定オプションとは無関係です。
(26158130) EMBEDDED_CONTENT_CONTAINS_SWIFTを廃し、ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIESを追加
EMBEDDED_CONTENT_CONTAINS_SWIFTが廃止になり、代わりにALWAYS_EMBED_SWIFT_STANDARD_LIBRARIESが追加になりました。この新しい設定は、Xcodeに常にSwift standard librariesを埋めこむように指定する物です。
ターゲットが直接使うか、もしくは、埋めこまれた他のプロダクトがSwiftを使っている場合に、この設定を使うことになります。
(20119003) 辞書や配列の空リテラルの挙動
暗黙的なブリッジ変換が削除されたことで、空の配列や辞書のリテラルはNSArrayやNSDictionaryとして型チェックされません(?) このような振る舞いは、しばしば意図せずに行われます。しかし、明示的に『[] as NSArray』や『[:] as NSDictionary』と指示することで、希望した動作をさせることが出来ます。
参考URL
Swift 3.0でなぜ「Cスタイルのforループ」「++/--演算子」などの仕様が廃止されたのか - Build Insider
http://www.buildinsider.net/column/ono-masayuki/004