詳解Swift改訂版(09)〜メモリ管理

2017. 02. 08
この記事は詳解 Swift 改訂版(初版第1刷)を元に、Xcode 8.2.1(Swift 3.0.2)下における差異を記述しています。



CHAPTER 09 メモリ管理



●9.2 強い参照の循環


・インスタンスが解放できない場合

List9-3 において、クラス Student 内の関数 description の定義でエラーが出ます。

func description: String {    // Expected '->'after function parameter tuple


クラス Student はプロトコル CustomStringConvertible を採用しているため、String 型の変数 description を定義しなければならないのですが、前の版である詳解 Swift では CustomStringConvertible を採用しておらず、String 型を返り値とする関数 description() で同じ機能を実装していたことによる単純なミスです。
したがって関数 description() を変数 description に修正する必要があります。

var description: String {


・弱い参照

最初の実行例において、変数 kaz に nil を代入した後に 弱い参照の変数 who を出力している文で警告が出ます。

print(who)    // Expression implicitly coerced from 'Student?' to Any


これは既に nil になっている変数 who をそのまま出力としているためなので、nil 合体演算子を使用した式などに修正すると良いでしょう。

print(who ?? "nil")



詳解Swift 第3版(Amazon)
 

詳解Swift改訂版(08)〜クラスと継承

2017. 02. 05
この記事は詳解 Swift 改訂版(初版第1刷)を元に、Xcode 8.2.1(Swift 3.0.2)下における差異を記述しています。



CHAPTER 08 クラスと継承



●8.1 クラス定義


・継承とメソッド呼び出し

List8-8 において、クラス A の関数 myclass の定義でエラーが出ます。

self.dynamicType.who()    // '.dynamicType' is deprecated. Use 'type(of: ...)' instead

Qiita/Xcode 8 Release Notes 日本語翻訳メモ」によると、Swift 3 で .dynamicType プロパティは廃止になり type(of:) 関数が追加されたようです。

これに関しては「Xcode 8 Release Notes(Xcode 8.0/Swift/New Features)」に、その旨の記述があります。

「dynamicType キーワードは Swift から削除されました。
その代わりに新しいプリミティブ関数 type(of:) が言語に追加されました。
式の方を取り出すために .dynamicType メンバを使用している既存のコードは、この新しいプリミティブに移行する必要があります。
sizeof と共に .dynamicType を使用しているコードは、
SE-0101で提供されている MemoryLayout 構造体に移行する必要があります。
(
SE-0096) 」

したがって myclass の定義は以下のようになります。

type(of: self).who()



●8.3 継承とサブクラスの定義


・クラスのメタタイプ

List8-18 において、上記の通り .dynamicType プロパティは廃止になったので type(of:) 関数に差し替える必要があります。

なおメタタイプについての詳細は「The Swift Programming Language (Swift 3.0.1): Types」で解説されています。


メタタイプ型

メタタイプ型はクラス型を含む構造体型、列挙型、そしてプロトコル型など、あらゆる型を表します。

クラス、構造体、または列挙型のメタタイプは、型名の後ろに .Type と続けます。
プロトコル型(実行時にプロトコルに準拠した具体的な型ではない)のメタタイプは、プロトコル名の後ろに .Protocol と続けます。
例えば、クラス型 SomeClass のメタタイプは SomeClass.Type、プロトコル SomeProtocol のメタタイプは SomeProtocol.Protocol となります。

値として型にアクセスするには接尾辞 self 式を使うことができます。
例えば SomeClass.self は SomeClass のインスタンスではなく SomeClass 自体を返します。
そして SomeProtocol.self は実行時に SomeProtocol に準拠した型のインスタンスではなく SomeProtocol 自体を返します。
以下の例で示すように型のインスタンスを伴って type(of:) 式を使用すると、インスタンスの動的なランタイム型の値としてアクセスすることができます。

class SomeBaseClass {
    class func printClassName() {
        print("SomeBaseClass")
    }
}
class SomeSubClass: SomeBaseClass {
    override class func printClassName() {
        print("SomeSubClass")
    }
}
let someInstance: SomeBaseClass = SomeSubClass()
// コンパイル時の someInstance の型は SomeBaseClass ですが、実行時の someInstance の型は SomeSubClass です。
type(of: someInstance).printClassName()
// "SomeSubClass" と出力

同一性演算子( === と !== )を使用して、インスタンスの実行時の型とコンパイル時の型が同じかをテストします。

if type(of: someInstance) === someInstance.self {
    print("someInstance の動的および静的型は同じ")
} else {
    print("someInstance の動的および静的型は異なる")
}
// "someInstance の動的および静的型は異なる" と出力

その型のメタタイプ値から型のインスタンスを構築するにはイニシャライザ式を使用します。
クラスのインスタンスの場合、呼び出されるイニシャライザには required キーワードを指定するか、final キーワードでクラス全体を指定する必要があります。

class AnotherSubClass: SomeBaseClass {
    let string: String
    required init(string: String) {
        self.string = string
    }
    override class func printClassName() {
        print("AnotherSubClass")
    }
}
let metatype: AnotherSubClass.Type = AnotherSubClass.self
let anotherInstance = metatype.init(string: "some string")



●8.4 解放時処理


・解放時処理とデイニシャライザ

List8-19 において、読み込むファイルのポインタ fp の定義でエラーが出るようになりました。

var fp: UnsafeMutablePointer<FILE> = nil    // error: nil cannot initialize specified type 'UnsafeMutablePointer<FILE>' (aka 'UnsafeMutablePointer<__sFILE>')

Qiita/Xcode 8 Release Notes 日本語翻訳メモ」によると、Swift 3 から null になる可能性のある UnsafePointer はオプショナルを使うようになったようです。

これに関しては「Xcode 8 Release Notes(Xcode 8.0/Swift/New Features)」に、その旨の記述があります。

「UnsafePointer、UnsafeMutablePointer、AutoreleasingUnsafeMutablePointer、OpaquePointer、Selector、そして NSZone 型は、現在 null にならないポインタ(つまり決して nil にならないポインタ)を表します。
現在 null になる可能性のあるポインタを表すには、例えば UnsafePointer<Int>? のようにオプショナルを使用します。

C からインポートされた型で(int * など)非オブジェクトのポインタは、現在 null 可否を考慮しています。

  • _Nonnull または NS_ASSUME_NONNULL_BEGIN/_END ブロックでマークされたポインタは、非オプショナル値として取り込まれます。
    例えば NSInteger * _Nonnull は UnsafeMutablePointer<Int> として取り込まれます。

  • _Nullable としてマークされたポインタはオプショナル値として取り込まれます。
    例えば NSInteger * _Nullable は UnsafeMutablePointer<Int>? として取り込まれます。

  • _Null_unspecified としてマークされたポインタ、または NS_ASSUME_NONNULL_BEGIN/_END ブロックの外にある注釈なしポインタは暗黙的開示オプショナル値として取り込まれます。
    例えば NSInteger * _Null_unspecified は UnsafeMutablePointer<Int>! として取り込まれます。

    Swift 標準ライブラリは一致するように調整されています。

    問題が起こる可能性の一つは、C の変数を使用する関数に null になる可能性のあるポインタを渡すことです。
    Swift はこれを直接には許可しませんが、代替の回避策として次のようにポインタサイズの整数値として渡すようにしてください。

    Int(bitPattern: nullablePointer)

    取り込んだポインタの "pointee" 型(例えば id * の id )は、たとえ注釈が付いていても常に _Nullable であるとは想定されません。
    ただし pointee 型の _Null_unspecified の暗黙的または明示的注釈は、引き続きオプショナルとして取り込まれます。
(SE-0055)」

したがって fp の定義は以下のようになります。

var fp: UnsafeMutablePointer<FILE>? = nil

またファイルから読み込んだ文字列を格納する変数 s の初期化でもエラーが出ます。

var s = String(UnicodeScalar(ch))    // error: 'init' has been renamed to 'init(describing:)'


これは「詳解Swift改訂版(05)〜基本的なデータ型」の「5.3 文字列と文字/UnicodeScalar 型」で述べたように、Int 型を引数とした UnicodeScalar 型のイニシャライザの返り値はオプショナル型になるためで、開示する必要があります。

var s = String(UnicodeScalar(ch)!)


その後に文字列を追加する append() でもエラーが出ます。(開示修正済み)

s.append(UnicodeScalar(ch)!)    // error: 'append' is unavailable: Replaced by append(_: String)


これも「詳解Swift改訂版(05)〜基本的なデータ型」の「5.3 文字列と文字/UnicodeScalar 型」で述べたように、append() の引数が UnicodeScalar 型に対応しなくなったためで、String 型のイニシャライザを使う必要があります。

s.append(String(UnicodeScalar(ch)!))

関数 readIt() において、「詳解Swift(8)〜クラスと継承」の「8.3 解放時処理/デイニシャライザを使った例」で述べたように、プレイグラウンドで試す場合には Resources へのテキストファイルの追加とファイルパスの取得が必要になりますが、ファイルパスを取得するためのクラスやメソッドが変更されたので修正する必要があります。
(「Blog by msyk/プロジェクトをXcode 8/Swift 3に変換した時の自動変換結果から変更点をチェックする」参照)

let path = (NSBundle.mainBundle().pathForResource("text", ofType: "txt"))!    // 'NSBundle' has been renamed to 'Bundle'

let path = (Bundle.mainBundle().pathForResource("text", ofType: "txt"))!    // Cannot call value of non-function type 'Bundle'

let path = (Bundle.mainBundle.pathForResource("text", ofType: "txt"))!    // 'mainBundle' has renamed to 'main'

let path = (Bundle.main.pathForResource("text", ofType: "txt"))!    // 'pathForResouce(_:ofType:)' has been renamed to 'path(forResource:ofType:)'

let path = (Bundle.main.path(forResource:"text", ofType: "txt"))!



Qiita/Xcode 8 Release Notes 日本語翻訳メモ

Blog by msyk/プロジェクトをXcode 8/Swift 3に変換した時の自動変換結果から変更点をチェックする

詳解Swift 第3版(Amazon)
 

詳解Swift改訂版(07)〜演算子

2017. 01. 28
この記事は詳解 Swift 改訂版(初版第1刷)を元に、Xcode 8.2.1(Swift 3.0.2)下における差異を記述しています。



CHAPTER 07 演算子



●7.1 Swiftの演算子


・剰余演算子

実数値に % 演算子を適用するとエラーが出るようになりました。

11.0 % 2.5        // error: '%' is unavailable: Use truncatingRemainder instead


Qiita/Xcode 8 Release Notes 日本語翻訳メモ」によると、Swift 3 から実数値に対して % 演算子は適用できなくなったようです。

これに関しては「Xcode 8 Release Notes(Xcode 8.0/Swift/New Features)」に、その旨の記述があります。

「FloatingPoint プロトコルは、ほとんどの IEEE 754 で要求される操作を満たすように拡張されました。
またプロトコルには最大の有限値または最小の正の正常値のような量を表す、多くの有用なプロパティも追加されています。(これらは Cで定義されている FLT_MAX などのマクロにも対応します)

変更のほとんどは追加ですが、既存のコードに影響を及ぼす変更が4つあります。

・浮動小数点型に対して % 演算子は利用できなくなりました。
 新しいメソッド formTruncatingRemainder(dividingBy:) は、必要に応じて古いセマンティクスを提供します。

・静的プロパティ .NaN は .nan に改名されました。

・静的プロパティ .quietNaN は冗長なので削除されました。
 代わりに
.nan を使用してください。

・述語  isSignaling は isSignalingNaN に改名されました。

(
SE-0067)」

エラーメッセージにある truncatingRemainder(dividingBy:) は剰余を返すメソッドで、Release Notes の説明にある formTruncatingRemainder(dividingBy:) は自身を剰余に書き換えるメソッドです。

func truncatingRemainder(dividingBy other: Self) -> Self

mutating func formTruncatingRemainder(dividingBy other: Self)

実行例を示します。

var x = 11.0

x.truncatingRemainder(dividingBy: 2.5)        // 1.0:剰余が返される
print(x)        // 11.0:x 自体は変化なし

x.formTruncatingRemainder(dividingBy: 2.5)        // 1.0:剰余を示す
print(x)        // 1.0:x が剰余に書き換えられる

x = 11.0        // 仕切り直し

-x.truncatingRemainder(dividingBy: 2.5)        // -1.0:x は変更されないので負にしても問題なし
print(x)        // 11.0

-x.formTruncatingRemainder(dividingBy: 2.5)        // error: 'inout Double' is not convertible to 'Double'
// x を書き換えるため負にするとエラーとなる

x *= -1.0

x.formTruncatingRemainder(dividingBy: 2.5)        // -1.0:もちろん x の内容が負なのは問題なし
print(x)        // -1.0



●7.2 演算子の定義


・二項演算子の定義

List7-1 において、二項演算子の宣言で警告が出るようになりました。

infix operator 〜 {    // Operator should no longer be declared with body; use a precedence group instead
    precedence 20
    associativity none
}

Qiita/Xcode 8 Release Notes 日本語翻訳メモ」によると、Swift 3 演算子を宣言する構文が変更されたようです。

これに関しては「Xcode 8 Release Notes(Xcode 8.0/Swift/New Features)」に、その旨の記述があります。

「新しい演算子を追加する構文が大幅に変更されました。
新しい言語モデルはマジックナンバーではなく、名前付き優先グループに基づくより意味のあるモデルを使用します。
これは >>> など新しい演算子の宣言にのみ影響し、== など既存の演算子に新たなオーバーロードを追加することには影響しません。(
SE-0077)」

具体的にどう変更されたかは「The Swift Programming Language (Swift 3.0.1)/Language Reference/Declarations」の「Operator Declaration」で解説されています。


・演算子の宣言

演算子の宣言はプログラムに新しい中置演算子、前置演算子、または後置演算子を導入し、operator キーワードを使用して宣言されます。

中置、前置、そして後置の3つの異なる結合性の演算子を宣言することができます。
演算子の結合性は、オペランドに対する演算子の相対的な位置を指定します。

演算子の宣言には3つの基本的な形式があり、それぞれの結合性に対応しています。
演算子の結合性は operator キーワードの前に infix、prefix、または postfix 宣言修飾子で演算子の宣言を示すことで指定されます。
各形式では、演算子の名前に Operators で定義されている演算子文字のみ含めることができます。

次の形式では新しい中置演算子を宣言します。

infix operator operator name: precedence group

infix operator は、式 1 + 2 でよく知られている加算演算子 (+) など、2つのオペランド間に記述される二項演算子です。

中置演算子ではオプションで優先度グループを指定することができます。

演算子の優先度グループを省略すると、Swift はデフォルトの優先度グループであり、TernaryPrecedence より高い優先度である DefaultPrecedence を使用して指定されます。
詳細は Precedence Group Declaration を参照してください。

次の形式では新しい前置演算子を宣言します。

prefix operator operator name

prefix operator は、式 !a における前置論理否定演算子 (!) など、オペランドの直前に記述される単項演算子です。

前置演算子の宣言では優先度レベルを指定することはできません。
前置演算子は結合規則を指定できません。

次の形式では新しい後置演算子を宣言します。

postfix operator operator name

postfix operator は、式 a! における後置開示指定演算子 (!) など、オペランドの直後に記述される単項演算子です。

前置演算子と同様、後置演算子の宣言でも優先度レベルを指定することはできません。
後置演算子も結合規則を指定できません。

新しい演算子を宣言した後、演算子と同名の静的メソッドを宣言することによって実装します。
静的メソッドは演算子が引数として取る値の型のいずれかのメンバであり、例えば Double と Int の乗算では Double または Int 構造体のどちらかの静的メソッドとして実装します。
前置または後置演算子を実装する場合、対応する prefix または postfix 宣言修飾子でメソッド宣言をマークする必要があります。
新しい演算子を作成・実装する方法の例については Custom Operators を参照してください。

演算子宣言の文法

演算子宣言 → prefix-operator-declaration­|postfix-operator-declaration­|infix-operator-declaration­

前置演算子宣言 → prefix­ operator­ operator­
後置演算子宣言 → postfix­ operator­ operator­
中置演算子宣言 → infix­ operator­ operator ­infix-operator-group­ opt­

中置演算子グループ → :­ precedence-group-name
 

これまで演算子の優先度は整数で指定していましたが、これからは優先度グループ(Precedence Group)で指定することになりました。
優先度グループの指定については「The Swift Programming Language (Swift 3.0.1)/Language Guide/Advanced Operators」の「Custom Operators/Precedence for Custom Infix Operators」で解説されています。


カスタム中置演算子(二項演算子)の優先度

カスタム中置演算子は、それぞれの優先度グループに属します。
優先度グループは他の中置演算子に対する演算子の優先度だけでなく、演算子の結合規則も指定します。
この特性が他の中置演算子との相互作用にどのような影響を及ぼすかについては「Precedence and Associativity」を参照してください。

優先度グループの位置を明示していないカスタム中置演算子は、三項演算子の優先度より高い優先度を持つデフォルトの優先度グループが与えられます。

次の例では優先度グループが AdditionPrecedence に属する +- という新しいカスタム中置演算子定義しています。

infix operator +-: AdditionPrecedence
extension Vector2D {
    static func +- (left: Vector2D, right: Vector2D) -> Vector2D {
        return Vector2D(x: left.x + right.x, y: left.y - right.y)
    }
}
let firstVector = Vector2D(x: 1.0, y: 2.0)
let secondVector = Vector2D(x: 3.0, y: 4.0)
let plusMinusVector = firstVector +- secondVector
// plusMinusVector is a Vector2D instance with values of (4.0, -2.0)

この演算子は2つのベクトルの x 値を加算し、最初のベクトルから2番目のベクトルの y 値を減算します。
本質的には"加法的"演算子なので、+ や - など加法的中置演算子と同じ優先度グループが与えられています。
Swift 標準ライブラリで提供されている演算子の優先度グループと結合規則設定の完全なリストについては Swift Standard Library Operators Reference を参照してください。
優先度グループについての詳細、および独自の演算子や優先度グループを定義する構文については Operator Declaration を参照してください。



前置演算子または後置演算子を定義する時に優先度を指定することはできません。
ただし同じオペランドに前置および後置の両方の演算子を適用する場合、後置演算子が最初に適用されます。
 

Swift 標準ライブラリで提供されている演算子の優先度グループと結合規則については「Swift Standard Library Operators」の「Table 2 Infix operators」に示されています。


表2 中置演算子

演算子説明結合規則優先度グループ
<<左ビットシフトなしBitwise shift
>>右ビットシフトなしBitwise shift
*乗算左結合Multiplication
/除算左結合Multiplication
%剰余左結合Multiplication
&*乗算(オーバーフローは無視)左結合Multiplication
&ビット論理積左結合Multiplication
+加算左結合Addition
-減算左結合Addition
&+加算(オーバーフローは無視)左結合Addition
&-減算(オーバーフローは無視)左結合Addition
|ビット論理和左結合Addition
^ビット排他的論理和左結合Addition
..<半開区間なしRange formation
...閉区間なしRange formation
is型検査左結合Casting
as, as?, as!型キャスト左結合Casting
??nil 合体右結合Nil coalescing
<未満なしComparison
<=以下なしComparison
>より大きいなしComparison
>=以上なしComparison
==等しいなしComparison
!=等しくないなしComparison
===同一なしComparison
!==同一ではないなしComparison
~=パターンマッチなしComparison
&&論理積左結合Logical conjunction
||論理和左結合Logical disjunction
?:三項条件右結合Ternary
=代入右結合Assignment
*=乗算代入右結合Assignment
/=除算代入右結合Assignment
%=剰余代入右結合Assignment
+=加算代入右結合Assignment
-=減算代入右結合Assignment
<<=左ビットシフト代入右結合Assignment
>>=右ビットシフト代入右結合Assignment
&=ビット論理積代入右結合Assignment
|=ビット論理和代入右結合Assignment
^=ビット排他的論理和代入右結合Assignment
 

既存の中置演算子の挙動に沿うものであれば、標準ライブラリで提供されている演算子の優先度グループを指定しても良いのでしょう。

ただしこれまでの優先度は整数の大小で示していましたが、優先度グループでは「The Swift Programming Language (Swift 3.0.1)/Language Reference/Declarations」の「Precedence Group Declaration」の解説にあるように、他の優先度グループに対しての相対的な高低で示すことになります。


・優先度グループの宣言

優先度グループの宣言は、プログラムに中置演算子の優先度のための新しいグループを導入します。
演算子の優先度は丸括弧でグループ化していない場合に、そのオペランドに演算子がどれくらい緊密に結びつくかを指定します。

優先度グループの宣言の形式は次の通りです。

precedencegroup precedence group name {
    higherThan: lower group names
    lowerThan: higher group names
    associativity: associativity
    assignment: assignment
}

lower group names と higher group names は、既存の優先度グループと新しい優先度グループとの関係を指定します。
lowerThan 優先度グループ属性は、現在のモジュールの外部で宣言された優先度グループを参照するためにのみ使用できます。
式 2 + 3 * 5 のように、2つの演算子が用いるオペランドが互いに競合する場合、そのオペランドは相対的により優先度の高い演算子に強く結びつきます。



lower group names と higher group names を使用して相互に関係する優先度グループは1つのリレーショナル階層に収まる必要がありますが、線形階層を構成する必要はありません。
つまり相対的な優先度が未定義の優先度グループを持つことができます。
そのような優先度グループの演算子は、丸括弧によるグループ化無しに互いに隣接して使用することはできません。

Swift は標準ライブラリで提供されている演算子に付随した多数の優先度グループを定義しています。
例えば加算 (+) および減算 (-) 演算子は AdditionPrecedence グループに属し、乗算 (*) および除算 (/) 演算子は MultiplicationPrecedence グループに属します。
Swift 標準ライブラリが提供する演算子および優先度グループの完全なリストについては、Swift Standard Library Operators Reference を参照してください。

演算子の associativity は丸括弧によるグループ化が存在しない場合に、同じ優先度レベルの演算子の順序をどのようにグループ化するかを指定します。
コンテキスト依存のキーワード left、right、none のいずれか1つを記述することによって演算子の結合規則を指定し、結合規則を省略した場合はデフォルトで none になります。
左結合グループの演算子は左から右に解釈します。
例えば減算演算子 (-) は左結合なので、式 4 -5- 6 は (4 -5) - 6 としてグループ化され、-7 と評価されます。
右結合グループの演算子は右から左に解釈し、none の結合規則を指定した演算子はまったく関連しません。
同じ優先度レベルの非結合演算子は、互いに隣接して存在させることはできません。
例えば none の結合規則を持つ < 演算子は、1 < 2 < 3 が有効な式ではないことを意味します。

優先度グループの assignment は、オプショナルチェーンを含む操作で使用する場合の演算子の優先度を指定します。
true を設定すると、対応する優先度グループの演算子は標準ライブラリからの代入演算子としてオプショナルチェーン中に同じグループ化規則を使用します。
それ以外の場合、つまり false が設定あるいは省略されていると、優先度グループの演算子は割り当てを実行しない演算子として同じオプショナルチェーンの規則に従います。

優先度グループの文法

優先度グループ宣言 → precedencegroup­ precedence-group-name­ {­ precedence-group-attributes­ opt­

優先度グループ属性 → precedence-group-attribute­ precedence-group-attributes ­opt­
優先度グループ属性 → precedence-group-relation­
優先度グループ属性 → precedence-group-assignment­
優先度グループ属性 → precedence-group-associativity­

優先度グループ関係性 → higherThan­precedence-group-names­
優先度グループ関係性 → lowerThan­precedence-group-names­

優先度グループ割当 → assignment­boolean-literal­

優先度グループ結合規則 → associativity­ :­ left­
優先度グループ結合規則 → associativity­ :­ right­
優先度グループ結合規則 → associativity­ :­ none­

優先度グループ名 → precedence-group-name­|precedence-group-name­ ,­ precedence-group-names­
優先度グループ名 → identifier
 

標準ライブラリで提供されている演算子の優先度グループの相対的な関係については「Qiita/Swift 3.0クイックガイド・後編」の「演算子の詳解/優先度グループ」に示されています。
(「GitHub/apple/swift-evolution/swift-evolution/0077-operator-precedence.md at master」参照)

これまで優先度を指定しない場合の規定値は100で三項演算子と同じでしたが、優先度グループを指定しない場合の規定値 DefaultPrecedence は三項演算子の TernaryPrecedence より上となっているので注意してください。

さて List7-1 の例の場合、整数を文字列に変換する演算子なので既存の演算子の優先度グループに属するような関連もなく、優先度が20と既存の演算子の優先度より低いので、新たな優先度グループを作成することになります。

precedencegroup StringWidthPrecedence {
    lowerThan: AssignmentPrecedence
    associativity: none
}

infix operator 〜: StringWidthPrecedence

また関数 〜 において、「詳解Swift改訂版(05)〜基本的なデータ型」の「5.3 文字列と文字/String 型のイニシャライザ」で述べたように、同じ値を複数回繰り返すイニシャライザ init(count:repeatedValue:) は init(repeating:count:) に改名され、Character 型および UnicodeScalar 型は指定できなくなり、String 型のみになりましたので修正する必要があります。

str = String(count:pad, repeatedValue:Character(" ")) + str        // error: 'init(count:repeatedValue:)' is unavailable: Renamed to init(repeating:count:) and reordered parameters

str = String(repeating: " ", count: pad) + str

更に実行例において、「詳解Swift改訂版(01)〜Swiftでプログラミング」の「1.2 制御構文/for 文」で述べたように、C 様式の for 文は for-in 文に書き換える必要があり、且つ関数 stride 書式が stride(through:by:) から stride(from:through:by:) に( stride(to:by:) も stride(from:to:by:) に)変更されましたので合わせて修正します。
(「Build Insider/Swift 3.0でなぜ「Cスタイルのforループ」「++/--演算子」などの仕様が廃止されたのか」参照)


for var wid = 2; wid <= 6; wid += 2 {    // error: C-style for statement has been removed in Swift 3

for wid in 2.stride(through: 6, by: 2) {    // error: 'stride(through:by:)' is unavailable: Use stride(from:through:by:) free function instead

for wid in stride(from:2, through:6, by:2) {


・単項演算子の定義

単項演算子( prefix・postfix )の宣言で、コードブロックを示す { } は不要になりました。

postfix operator % {}    // Operator should no longer be declared with body

postfix operator %    // prefix も同様


・引数の変数の値を変更するには

List7-3 において、本書では演算子 >? の優先度を代入演算子と同じ90にしていますが、代入演算子の優先度グループ AssignmentPrecedence の結合規則が右結合(本書では 'なし')であるため、新たに優先度グループを作ることにします。

precedencegroup ComparisonAssignmentPrecedence {
    lowerThan: AssignmentPrecedence    // AssignmentPrecedence より上にするなら higherThan
    associativity: none
}

infix operator >? : ComparisonAssignmentPrecedence

また関数 >? の inout 引数は「詳解Swift改訂版(02)〜関数」の「2.2 関数定義におけるさまざまな設定/inout 引数」で述べたように、: の後ろに書くことになったので注意してください。

func >? (inout lhs:Double, rhs:Double) {    // 'inout' before a parameter name is not allowed. place it before the parameter type instead

func >? (lhs:inout Double, rhs:Double) {


・短絡評価をする演算子の定義

List7-7 において、@autoclosure の記述でエラーが出るようになりました。

func skip(cond:Bool, @autoclosure _ arg:() -> Int) {    // error: @autoclosure is now an attribute on a parameter type, instead of on the parameter itself

Developers.IO/[iOS][Swift] Swift 3.0の変更点まとめ」によると、Swift 3 から@autoclosure の記述位置がパラメータの属性からパラメータ型の属性に戻ったようです。

func skip(cond:Bool, _ arg:@autoclosure() -> Int) {

また List7-8 において、中置演算子 ⊽ の優先度は論理和 || と同じとありますので、優先度グループは LogicalDisjunctionPrecedence として宣言します。

infix operator ⊽: LogicalDisjunctionPrecedence



Qiita/Xcode 8 Release Notes 日本語翻訳メモ

小野和俊のブログ/プログラマーが覚えておきたい英単語

GitHub/jats-ug/translate/translate/Dictionary.md at master

GitHub/Swift 2.0: Vector3D Vector2D

GitHub/apple/swift-evolution/swift-evolution/0077-operator-precedence.md at master

スタジオガラゴ/The Swift Programming Language 日本語訳

Qiita/Swift 3.0クイックガイド・後編

Build Insider/Swift 3.0でなぜ「Cスタイルのforループ」「++/--演算子」などの仕様が廃止されたのか

Developers.IO/[iOS][Swift] Swift 3.0の変更点まとめ

詳解Swift 第3版(Amazon)
 

詳解Swift改訂版(06)〜パターン

2017. 01. 18
この記事は詳解 Swift 改訂版(初版第1刷)を元に、Xcode 8.2.1(Swift 3.0.2)下における差異を記述しています。



CHAPTER 06 パターン



●6.1 タプル


・タプルの概要

本文ではタプル同士の比較はできないとありますが、前版の「詳解Swift(6)〜パターン」で述べたように特定条件下での比較は可能です。

(1, 2) == (1, 2)        // true



●6.2 列挙型


・シンプルな列挙型

列挙型の定義内でもメンバ名だけの参照はエラーが出るようになりました。

case .Up: return Right        // error: enum element 'Right' cannot be referenced as an instance member
case .Down: return Left        // error: enum element 'Left' cannot be referenced as an instance member
case .Right: return Down        // error: enum element 'Down' cannot be referenced as an instance member
case .Left: return Up        // error: enum element 'Up' cannot be referenced as an instance member

Qiita/Xcode 8 Release Notes 日本語翻訳メモ」によると、Swift 3 から要素のアクセスに「.」が必要になったようです。

これに関しては「Xcode 8 Release Notes(Xcode 8.0/Swift/New Features)」に、その旨の記述があります。

「インスタンスメソッド内でインスタンスメンバとして列挙型の要素にアクセスすると、コンパイラがエラーを出すようになりました。
例えば、

enum Color {
    case red, green, blue
 
    func combine(with color: Color) -> Color {
        return red
    }
}

これは Swift 2.2 では有効です。
Swift 3 での正しい方法は以下のように記述します。

return .red

(
SE-0036) 」

したがって実行文は以下のようになります。

case .Up: return .Right
case .Down: return .Left
case .Right: return .Down
case .Left: return .Up


・列挙型に対するメソッドとプロパティ

List6-5 において、上記の通り列挙型の要素にアクセスするには "." が必要なため、switch 文の case 節で指定している Right と Left は "." を加えなければなりません。



●6.3 共用型の列挙型


・if-case 文

変数 t の内容が残高 1200 円以上のプリペイドカードかどうかの例で、「詳解Swift改訂版(04)〜オプショナル」の「4.2 オプショナル束縛構文/if-let 文」で説明したように、Swift 3 から条件句は "where" ではなく "," で区切るように変更されました。

if case .カード(let y, _) = t where y > 1200 {        // Expected ',' joining parts of a multi-clause condition

if case .カード(let y, _) = t, y > 1200 {


・for-in 文で case パターンを使う

Ticket 型の要素を持つ配列 passes は「詳解 Swift 改訂版 サンプルダウンロード」の「samples/Chap06/p150.swift」からコピーすると便利です。

また前述の条件区の区切りが "where" から "," に変更された件は if、guard、while 文に対してであり、for-in 文では適用されないので例文通り "where" のままとなります。


・オプショナル型と列挙型

実行例でメンバ Some を使用した場合にエラーが出ます。

if case let .Some(x) = opi { print(x) }        // error: 'Some' has been renamed to 'some'

これは Optional の定義が変更されたためです。

public enum Optional<Wrapped> : ExpressibleByNilLiteral {
    case none
    case some(Wrapped)
    public init(_ some: Wrapped)
(以下略)
}

したがって以下のように修正することになります。

if case let .some(x) = opi { print(x) }



Qiita/Xcode 8 Release Notes 日本語翻訳メモ

詳解Swift 第3版(Amazon)
 

詳解Swift改訂版(05)〜基本的なデータ型

2017. 01. 13
この記事は詳解 Swift 改訂版(初版第1刷)を元に、Xcode 8.2.1(Swift 3.0.2)下における差異を記述しています。



CHAPTER 05 基本的なデータ型



●5.1 整数と実数


・範囲型と区間型

Qiita/Swift 3.0のRangeまとめ」や「Qiita/Swift 3のRange徹底解説」で述べられているように、Swift 3 で範囲型と区間型の仕様が変わりました。

Swift 2.2 での区間型 HalfOpenInterval<T> と ClosedInterval<T> は Swift 3.0 では Range<T> と ClosedRange<T> になり、これまで閉区間のなかった(閉区間を指定できるが実際には半開区間だった)範囲型 Range<T> は CountableRange<T> と CountableClosedRange<T> に分けられました。
(特に Range<T> が範囲型から区間型に変更されたことに注意が必要です。)

範囲型区間型
半開区間閉区間半開区間閉区間
Swift 2.2Range<T>-HalfOpenInterval<T>ClosedInterval<T>
Swift 3.0Countable
Range<T>
Countable
ClosedRange<T>
Range<T>ClosedRange<T>
整数Int
UInt
実数Double
Float
××
文字
文字列
Character
String
××
BoundComparable
Strideable××
Bound.StrideSignedInteger××
RandomAccessCollection××
for-in 文での利用××
switch 文での利用

したがって型宣言をした範囲演算子による初期化は以下のようになります。

var inth: HalfOpenInterval<Int> = 0..<10        // error: 'HalfOpenInterval' has been renamed to 'Range'
var inth: Range<Int> = 0..<10

var intc: ClosedInterval<Int> = 0...10        // error: 'ClosedInterval' has been renamed to 'ClosedRange'
var inc: ClosedRange<Int> = 0...10

var rg: Range<Int> = 0..<10        // 範囲型ではなく半開区間型になる
var rgh: CountableRange<Int> = 0..<10

var rgc: CountableClosedRange<Int> = 0...10

イニシャライザを使った初期化は以下のようになります。

var inth = Range<Int>(uncheckedBounds: (0, 10))
var intc = ClosedRange<Int>(uncheckedBounds: (0, 10))
var rgh = CountableRange<Int>(uncheckedBounds: (0, 10))
var rgc = CountableClosedRange<Int>(uncheckedBounds: (0, 10))

パターンマッチ演算子の例において、型を指定せず範囲演算子に文字列(または文字や実数)を指定した場合は区間型に、整数を指定した場合は範囲型になります。

var sintv = "archer" ... "saber"        // ClosedRange("archer"..."saber")

var rg = -5 ... 5        // CountableClosedRange(-5...5)

let intv = 0.0 ..< 8.0        // Range(0.0..<8.0)



●5.2 配列


・配列とプロトコル

配列の要素を逆順に並べ換える reverse() メソッドはエラーが出るようになりました。

for item in s.reverse() { print(item) }        // error: 'reverse()' has been renamed to 'reversed()'

Study Swift/Reverse Array in Swift 2.2/3.0」によると、Swift 3 から reversed() に改名されたようです。

for item in s.reversed() { print(item) }        // 冬 秋 夏 春


・配列のイニシャライザ

イニシャライザ init(count:Int, repeatedValue:T) はエラーが出るようになりました。

var data = [Double](count:10, repeatedValue:0.0)        // error: argument 'repeatedValue' must precede argument 'count'

articles of samekard/Swift2.2からSwift3.0への変換を行ってみて」によると、Swift 3 から init(repeating:T, count:Int) に変更されたようです。

var data = [Double](repeating:0.0, count:10)        // [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]


・配列のメソッド

メソッド insert(_: T, atIndex: Int) はエラーが出るようになりました。

s.insert("零", atIndex:0)        // error: incorrect argument label in call (have '_:atIndex:', expected '_:at:')

Swift 3 から insert(_: T, at: Int) に変更されたようです。

s.insert("零", at: 0)        // ["零", "壱", "弐", "参"]

また removeAtIndex(_: Int) -> T もエラーが出るようになりました。

let one = s.removeAtIndex(1)        // error: 'removeAtIndex' has been renamed to 'remove(at:)'

Swift 3 から remove(at: Int) -> T に改名されたようです。

let one = s.remove(at: 1)        // "壱"



●5.3 文字列と文字


・String型のイニシャライザ

String 型のイニシャライザで配列を渡すとエラーが出るようになりました。

let b = String([6001, 5210])        // error: 'init' has been renamed to 'init(describing:)'

Developers.IO/[Swift 3] 型名を取得する」によると、init(describing:) が Swift 3 で追加されたようです。

let b = String(describing: [6001, 5210])        // "[6001, 5210]"

また同じ値を複数回繰り返すイニシャライザ init(count:repeatedValue:) は init(repeating:count:) に改名され、Character 型および UnicodeScalar 型は指定できなくなり、String 型のみになりました。
(String 型を繰り返す init(count:repeatedValue:) は元々無かった?)

// init(count:repeatedValue:)

let char: Character = "花"
let sc = String(count: 10, repeatedValue: char)        // error: 'init(count:repeatedValue:)' is unavailable: Renamed to init(repeating:count:) and reordered parameters

let str: String = "華"
let ss = String(count: 10, repeatedValue: str)        // error: cannot invoke initializer for type 'String' with an argument list of type '(count: Int, repeatedValue: String)'

let us = (UnicodeScalar(0x83ef))!
let su = String(count: 10, repeatedValue: us)        // error: 'init(count:repeatedValue:)' is unavailable: Renamed to init(repeating:count:) and reordered parameters


// init(repeating:count:)

let sc = String(repeating: char, count: 10)        // error: 'init(repeating:count:)' is unavailable: Replaced by init(repeating: String, count: Int)

let ss = String(repeating: str, count: 10)        // "華華華華華華華華華華"

let su = String(repeating: us, count: 10)        // error: 'init(repeating:count:)' is unavailable: Replaced by init(repeating: String, count: Int)


・UnicodeScalar 型

Int 型と String 型を引数とした UnicodeScalar 型定数の比較でエラーが出るようになりました。

let us1 = UnicodeScalar(0x83ef)        // Int 型引数
let us2 = UnicodeScalar("澪")        // String 型引数
let us3 : UnicodeScalar = "箒"        // unicodeScalarLiteral

us1 > us2        // error: binary operator '>' cannot be applied to two 'UnicodeScalar?' operands

これは「Apple Developer Documentation/Swift Standard Library/UnicodeScalar」で説明されているように、Int 型や String 型を引数としたイニシャライザの返り値はオプショナル型であり、また「詳解Swift改訂版(04)〜オプショナル」で述べたように比較演算子がオプショナル型の値を受け付けなくなったためです。
したがって比較するには開示する必要があります。

type(of: us1)        // Optional<UnicodeScalar>.Type
type(of: us2)        // Optional<UnicodeScalar>.Type
type(of: us3)        // UnicodeScalar.Type

us1! > us2!        // true

List5-3 においても、定数 first と last は Int 型を引数としたイニシャライザのためオプショナル型になるので、プロパティ unicodeScalars の値と比較するには開示する必要があります。

let first = UnicodeScalar(0x3041)        // Optional<UnicodeScalar>.Type
let last = UnicodeScalar(0x309f)        // Optional<UnicodeScalar>.Type

for sc in text.unicodeScalars {        // String.UnicodeScalarView.Type
    if sc >= first && sc <= last {        // error: binary operator '>=' cannot be applied to operands of type 'String.UnicodeScalarView.Iterator.Element' (aka 'UnicodeScalar') and 'UnicodeScalar?'


let first = UnicodeScalar(0x3041)!        // UnicodeScalar.Type
let last = UnicodeScalar(0x309f)!        // UnicodeScalar.Type

また String 型のインスタンスメソッド append() の引数は String 型もしくは Character 型 のみに対応しているので、UnicodeScalar 値を使うにはイニシャライザを使う必要があります。
(「Apple Developer Documentation/Swift Standard Library/String」参照)

kana.append(sc)        // error: 'append' is unavailable: Replaced by append(_: String)

kana.append(String(sc))


・指定位置の文字および部分文字列の取り出し方

本文では使用していませんが、指定範囲の文字列を取得する subscript は範囲型(の旧 Range<String.Index> )ではなく区間型になり、半開区間が subscript(Range<String.Index>)、閉区間が subscript(ClosedRange<String.Index>) となっています。

文字列中の任意の文字、部分文字列を参照する例ですが、プロパティ startIndex や endIndex で示しているインデックス位置を前後させるメソッド successor() と predecessor() は廃止され、代わりに index(after: String.Index) と index(before: String.Index) を使用することになりました。

また指定した値分を移動させる advance() も廃止されて代わりに index(String.Index, offsetBy: String.IndexDistance) か index(String.Index, offsetBy: String.IndexDistance, limitedBy: String.Index) を使用することになっています。
(「大津真 Web/Swift 3 文字列操作(その2)」参照)

print( str[str.startIndex.successor()] )        // error: 'successor()' is unavailable: To get the next index call 'index(after:)' on the CharacterView instance that produced the index.
print( str[advance(str.startIndex, 9)] )        // error: use of unresolved identifier 'advance'

print( str[str.endIndex.predecessor()] )        // error: 'predecessor()' is unavailable: To get the previous index call 'index(before:)' on the CharacterView instance that produced the index.
print( str[advance(str.endIndex, -3)] )        // error: use of unresolved identifier 'advance'

let x = advance(str.startIndex, 7)        // error: use of unresolved identifier 'advance'
let y = advance(x, 5)        // error: use of unresolved identifier 'advance'

簡略化のため startIndex と endIndex を定数に入れ、メソッドを修正すると以下のようになります。

let sIndex = str.startIndex        // 0
let eIndex = str.endIndex        // 19

print( str[sIndex] )        // 俺
print( str[str.index(after: sIndex)] )        // 、
print( str[str.index(sIndex, offsetBy: 9)] )        // グ

print( str[str.index(before: eIndex)] )        // 。
print( str[str.index(eIndex, offsetBy: -3)] )        // ま

let x = str.index(sIndex, offsetBy: 7)        // 7
let y = str.index(x, offsetBy: 5)        // 13

List5-5 において、String.Index 型の変数 x1 と x2 はインクリメント演算子が使えないだけでなく、Int 値との演算もできません。

x1 += 1; x2 += 1        // error: binary operator '+=' cannot be applied to operands of type 'String.Index' (aka 'String.CharacterView.Index') and 'Int'

したがってインデックス位置を進めるメソッド index(after:) を使用する必要があります。

x1 = s1.index(after: x1); x2 = s2.index(after: x2)

なお subscript で単純な整数を使えない理由に関しては「Medium/Swift・iOSコラム/Swift 3のStringのCharacter Viewを、なぜIntでsubscript出来ないのか分からない」と「Medium/Swift・iOSコラム/Swift 3のStringのViewに対して、Intでsubscript出来ない理由」を参照すると良いでしょう。


・String 型のメソッド

メソッド append() について、上述の通り現在は append(String) と append(Character) は使えますが UnicodeScalar 型を引数にすることはできませんので注意してください。

let a: Character = "a"
let b: String = "bbb"
var c: String = "ccc"

c.append(a)        // ccca
c.append(b)        // cccabbb

let d: UnicodeScalar = "d"

c.append(d)        // error: 'append' is unavailable: Replaced by append(_: String)

メソッド appendContentsOf() は append(contentsOf:) に、insert(_:atIndex:) は insert(_:at:) に、insertContentsOf(_:at:) は insert(contentsOf:at:) に改名されています。

let e: [Character] = ["e", "E"]        // Character 型を要素とする CollectionType 型

// append(contentsOf:)

c.appendContentsOf(e)        // error: 'appendContentsOf' has been renamed to 'append(contentsOf:)'
c.append(contentsOf: e)        // cccabbbeE

let sIndex = c.startIndex
let eIndex = c.endIndex

// insert(_:at:)

c.insert("f", atIndex: c.index(sIndex, offsetBy: 8))        // error: incorrect argument label in call (have '_:atIndex:', expected '_:at:')
c.insert("f", at: c.index(sIndex, offsetBy: 8))        // cccabbbefE

// insert(contentsOf:at:)

c.insertContentsOf(e, at: eIndex)        // error: 'insertContentsOf(_:at:)' has been renamed to 'insert(contentsOf:at:)'
c.insert(contentsOf: e, at: eIndex)        // cccfabbbefeEE
// 直前の insert(_:at:) で eIndex の示す位置が "E の次" ではなく "E" になるため cccabbbefEeE とはならない

メソッド removeAtIndex() は remove(at:) に改名されています。

c.removeAtIndex(sIndex)        // error: 'removeAtIndex' has been renamed to 'remove(at:)'
c.remove(at: sIndex)        // c

余談ですが remove(at:) で試しに endIndex の定数を指定したところ(そのインデックスに値が存在しているのに)エラーになりました。

c.remove(at: eIndex)        // error:Execution was interrupted, reason: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode= 0x0).

不思議に思い前後関係を調べると、endIndex と index(after:) で求めたその次のインデックスが同じという結果でした。

c.index(before: eIndex)        // 8
eIndex        // 9
c.index(after: eIndex)        // 9

理由は分かりませんが subscript でも endIndex を指定するとエラーになり、当該インデックスを指定するには index(after:) で指定しなければならないようなので注意が必要です。

print(c)        // ccabbbefeEE

print(c[c.index(before: eIndex)])        // e
print(c[eIndex])        // error:Execution was interrupted, reason: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode= 0x0).
print(c[c.index(after: eIndex)])        // E

メソッド removeRange() は半開区間の removeSubrange(Range<String.Index>) と閉区間の removeSubrange(ClosedRange<String.Index>) に改名されました。

let x = c.index(sIndex, offsetBy: 1)        // 1
let y = c.index(x, offsetBy: 2)        // 3
let xy1 = x ..< y        // 1..<3
let xy2 = x ... y        // 1...3

print(c)        // ccabbbefeE

c.removeRange(xy1)        // error: 'removeRange' has been renamed to 'removeSubrange'

c.removeSubrange(xy1)        // cbbbefeE
c.removeSubrange(xy2)        // cefeE

メソッド replaceRange(_:with:) は半開区間と閉区間、置換するものが Character 型の文字を要素とする CollectionType 型か String 型の文字列かの4種類になりました。

半開区間閉区間
文字
コレクション
replaceSubrange
(Range<String.Index>, with: C)
replaceSubrange
(ClosedRange<String.Index>, with: C)
文字列replaceSubrange
(Range<String.Index>, with: String)
replaceSubrange
(ClosedRange<String.Index>, with: String)

var z = "012345"
let g: [Character] = ["g", "G"]
let h: String = "hhh"

z.replaceRange(xy1, with: g)        // error: 'replaceRange(_:with:)' has been renamed to 'replaceSubrange'

z.replaceSubrange(xy1, with: g)        // 0gG345("12"を"gG"に置換)
z.replaceSubrange(xy1, with: h)        // 0hhh345("gG"を"hhh"に置換)
z.replaceSubrange(xy2, with: g)        // 0gG345("hhh"を"gG"に置換)
z.replaceSubrange(xy2, with: h)        // 0hhh45("gG3"を"hhh"に置換)



●5.5 集合


・集合の型宣言と初期値

Table5-3 で紹介しているメドッソのほとんどが改名されています。

集合旧メソッド新メソッド
和集合union(_:) -> Setunion(_:) -> Set
unionInPlace(_:)formUnion(_:)
差集合subtract(_:) -> Setsubtracting(_:) -> Set
subtractInPlace(_:)subtract(_:)
積集合intersect(_:) -> Setintersection(_:) -> Set
intersectInPlace(_:)formIntersection(_:)
対称差集合exclusiveOr(_:) -> SetsymmetricDifference(_:) -> Set
exclusiveOrInPlace(_:)formSymmetricDifference(_:)

// 和集合

var a = Set<Int>(0...3)        // {2, 0, 1, 3}
var b = Set<Int>(3...6)        // {5, 6, 3, 4}
var c = Set<Int>(4...7)        // {5, 6, 7, 4}

let z = a.union(b)        // {2, 4, 5, 6, 0, 1, 3}
a.unionInPlace(c)        // error: 'unionInPlace' has been renamed to 'formUnion(_:)'
a.formUnion(c)        // {2, 4, 5, 6, 7, 0, 1, 3}

// 差集合

var d = Set<Int>(0...3)        // {2, 0, 1, 3}
var e = Set<Int>(3...6)        // {5, 6, 3, 4}
var f = Set<Int>(2...5)        // {2, 0, 1, 3}

let y = d.subtracting(e)        // {2, 0, 1}
d.subtractInPlace(f)        // error: 'subtractInPlace' has been renamed to 'subtract(_:)'
d.subtract(f)        // {0, 1}

// 積集合

var g = Set<Int>(0...3)        // {2, 0, 1, 3}
var h = Set<Int>(3...6)        // {5, 6, 3, 4}
var i = Set<Int>(2...5)        // {5, 2, 3, 4}

g.intersect(h)        // error: 'intersect' has been renamed to 'intersection(_:)'
var x = g.intersection(h)        // {3}
g.intersectInPlace(i)        // error: 'intersectInPlace' has been renamed to 'formIntersection(_:)'
g.formIntersection(i)        // {2, 3}

// 対称差集合

var j = Set<Int>(0...3)        // {2, 0, 1, 3}
var k = Set<Int>(3...6)        // {5, 6, 3, 4}
var l = Set<Int>(2...5)        // {5, 2, 3, 4}

var w = j.exclusiveOr(k)        // error: 'exclusiveOr' has been renamed to 'symmetricDifference(_:)'
var w = j.symmetricDifference(k)        // {5, 6, 2, 0, 1, 4}
j.exclusiveOrInPlace(l)        // error: 'exclusiveOrInPlace' has been renamed to 'formSymmetricDifference(_:)'
j.formSymmetricDifference(l)        // {5, 0, 1, 4}

したがって実行例で積集合を取っているメソッドは修正する必要があります。

jset.intersectInPlace(w)        // error: cannot convert value of type '[String]' to expected argument type 'Set<String>'

jset.formIntersection(w)        // ["幽霊"]



Qiita/Swift 3.0のRangeまとめ

Qiita/Swift 3のRange徹底解説

Study Swift/Reverse Array in Swift 2.2/3.0

articles of samekard/Swift2.2からSwift3.0への変換を行ってみて

Developers.IO/[Swift 3] 型名を取得する

大津真 Web/Swift 3 文字列操作(その2)

Qiita/「文字数」ってなぁに?〜String, NSString, Unicodeの基本〜

Medium/Swift・iOSコラム/Swift 3のStringのCharacter Viewを、なぜIntでsubscript出来ないのか分からない

Medium/Swift・iOSコラム/Swift 3のStringのViewに対して、Intでsubscript出来ない理由

詳解Swift 第3版(Amazon)
 






QuietControl 30 wireless headphones
Calendar
10 | 2017/11 | 12
Sun Mon Tue Wed Thu Fri Sat
- - - 1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 - -
Recent Articles
iTunes


Swift
Categories
Tips
Profile

水月杏香

Author:水月杏香
永遠の初心者プログラマ。

Wish List
WACOM


ARC
Technical Q&A
情報プロパティリストキー
Start Developing iOS Apps Today
BOSE

QuietControl 30 wireless headphones
Reference
NSApplicationDelegateプロトコル
NSArrayクラス
NSAutoreleasePoolクラス
NSBundleクラス
NSBundle UIKit追加分
NSCalendarクラス
NSCoderクラス
NSCodingプロトコル
NSCopyingプロトコル
NSDataクラス
NSDateクラス
NSDateFormatterクラス
NSDictionaryクラス
NSEntityDescriptionクラス
NSEnumeratorクラス
NSErrorクラス
NSExceptionクラス
NSFetchRequestクラス
NSFileHandleクラス
NSFileManagerクラス
NSIndexPathクラス
NSIndexPath UIKit追加分
NSKeyedArchiverクラス
NSKeyedUnarchiverクラス
NSKeyValueCodingプロトコル
NSLocaleクラス
NSManagedObjectクラス
NSManagedObjectContextクラス
NSManagedObjectModelクラス
NSMutableArrayクラス
NSMutableCopyingプロトコル
NSMutableDictionaryクラス
NSMutableSetクラス
NSNotificationクラス
NSNotificationCenterクラス
NSNullクラス
NSNumberクラス
NSObjectクラス
NSObject UIKit追加分
NSObjectプロトコル
NSPersistentStoreクラス
NSPersistentStoreCoordinatorクラス
NSPredicateクラス
NSPropertyListSerializationクラス
NSRunLoopクラス
NSSetクラス
NSStringクラス
NSString UIKit追加分
NSTimerクラス
NSTimeZoneクラス
NSURLクラス
NSURLProtectionSpaceクラス
NSURLRequestクラス
NSUserDefaultsクラス
NSValueクラス

UIActionSheetクラス
UIActionSheetDelegateプロトコル
UIActivityIndicatorViewクラス
UIAlertViewクラス
UIAlertViewDelegateプロトコル
UIApplicationクラス
UIApplicationDelegateプロトコル
UIBarButtonItemクラス
UIBarItemクラス
UIButtonクラス
UIColorクラス
UIControlクラス
UIDatePickerクラス
UIDeviceクラス
UIEventクラス
UIFontクラス
UIGestureRecognizerクラス
UIImageクラス
UIImageViewクラス
UIKit Function
UILabelクラス
UINavigationControllerクラス
UINavigationItemクラス
UIPickerViewクラス
UIPickerViewDataSourceプロトコル
UIPickerViewDelegateプロトコル
UIPinchGestureRecognizerクラス
UIResponderクラス
UIScreenクラス
UIScrollViewクラス
UISearchBarクラス
UISearchBarDelegateプロトコル
UISegmentedControlクラス
UISliderクラス
UISwipeGestureRecognizerクラス
UISwitchクラス
UITableViewクラス
UITableViewCellクラス
UITableViewControllerクラス
UITableViewDataSourceプロトコル
UITableViewDelegateプロトコル
UITapGestureRecognizerクラス
UITextFieldクラス
UITextFieldDelegateプロトコル
UITextInputTraitsプロトコル
UITextViewクラス
UITextViewDelegateプロトコル
UIToolbarクラス
UITouchクラス
UIViewクラス
UIViewControllerクラス
UIWebViewクラス
UIWebViewDelegateプロトコル
UIWindowクラス

AVAudioPlayerクラス
AVAudioPlayerDelegateプロトコル

CADisplayLinkクラス
CAEAGLLayerクラス
CALayerクラス

CGAffineTransform
CGBitmapContext
CGColor
CGColorSpace
CGContext
CGGeometry
CGImage
CGPath

EAGLContextクラス
EAGLDrawableプロトコル

Foundation Constants
Foundation Data Types
Foundation Functions

MPMediaItemクラス
MPMediaItemArtworkクラス
MPMediaPlaylistクラス
MPMediaPropertyPredicateクラス
MPMediaQueryクラス
MPMusicPlayerControllerクラス

Randomization Services

System Sound Services
Amazon


OpenGL ES
SQLite
Monthly Archives
Recent Comments
Recent TrackBacks
RSS Link
Visitors
QR Code
QR