詳解Swift(10)〜プロトコル

2016. 10. 14
この記事は詳解 Swift(初版第1刷)を元に、Xcode 7.3.1(Swift 2.2)下における差異を記述しています。



CHAPTER 10 プロトコル



●10.1 プロトコルの宣言


・プロトコルの概要と例

List10-2 において、クラス Date にプロトコル Printable を採用しようとするとエラーが出ます。

class Date : Printable {        // error: 'Printable' has been renamed to 'CustomStringConvertible'

これは「Swift 1.2からSwift 2への移行 #cocoa_kansai」で示されているように、Swift 2.0 からプロトコル名が Printable から CustomStringConvertible に変更されたためのようです。

また List10-3 において、列挙型 Sex のメンバ Male、Female を switch 文で分岐する際、本書では「.」無しで指定していますが正常に動作します。
ただしプレイグラウンドの入力補完では「.」が入るので、「.」を入れた方が良いでしょう。

enum Sex : CustomStringConvertible {
    case Male, Female
    var description: String {
        switch self {
        case Male: return "男"             // 「.」が無くても正常に動く
        case .Female: return "女"        // 本来は「.」付きでメンバを指定する(入力補完では「.」が入る)
        }
    }
}


・プロトコルの使用例

本文での説明が少々分かり難いのですが、プロトコル Foretellable を採用したクラス Monthology の実行では以下のようにファイルを作成しています。

Person.swift:List10-2(クラス Date)+List10-3(列挙型 Sex)+List10-4(構造体 Person)
Foretellable.swift:List10-5(プロトコル Foretellable)
Monthology.swift:List10-6(変数 oracles・initFlag、クラス Monthology)
Rand.swift:List1-9(クラス Rand)+ List10-7(関数 shuffleArray)
main.swift:実行例(定数 she、変数 teller)

ちなみに「SBクリエイティブ/詳解 Swift サンプルダウンロード」には、本書中では中略されている変数 oracles のメッセージが略さずに載っています。

なお「詳解Swift(8)〜クラスと継承」で説明したように、プレイグラウンドで Sources フォルダにこれらのソースファイルを追加して試そうとしても、可視性の問題でうまくいかないのでご注意ください。

全ての定義を1つのプレイグラウンドファイル上に記述して試す場合、クラス Randや関数 shuffleArrayの定義については前方参照を考慮する必要はありませんが、乱数生成に使う種変数 seedの定義は(shuffleArray を呼び出す)クラス Monthology の定義より前に記述する必要があります。
Monthology の定義の後に seed の定義を記述した場合、shuffleArray の呼び出し時に「Use of unresolved identifier 'shuffleArray'」とエラーが出ます。

またクラス Monthology のインスタンスメソッド predict 内で使用している変数 s は、変更されないようなので定数にしたらどうかと警告が出ますので定数にしていいでしょう。

var s = "\(mon)月生まれの\(person.name)さんの\(subject)は、"        // Variable 's' was never mutated; consider changing to 'let' constant


let s = "\(mon)月生まれの\(person.name)さんの\(subject)は、"



●10.2 プロトコルと型


・プロトコルの継承

関数 predict の宣言でエラーが出ますが、これは「詳解Swift(2)〜関数(2.1 関数定義の基本/外部引数名)」で述べたように、関数の内部引数名と外部引数名を同じにするための # は使用できなくなったためで、第1引数の外部引数名は明示する必要があります。

func predict(#date: Date) -> String        // エラー


func predict(date date: Date) -> String



●10.4 プロトコルと付属型


・ネスト型とプロトコル

List10-10において、typealias を使って付属型を宣言すると警告が出るようになりました。

protocol Vector2D {
    typealias DataType        // Use of 'typealias' to declare associated types is deprecated; use 'associatedtype' instead
    var x : DataType { get set }
    var y : DataType { get set }
}

これに関しては「Xcode 7 Release Notes(Xcode 7.3 Release Notes/New Features/Swift)」に、typealias の代わりに associatedtype を使うようにと記述があります。(「Qiita/Swift 2.2の新機能: SE-0011: 付属型を宣言するための typealias キーワードを associatedtype に置き換える」参照)

「プロトコルにおける付属型は宣言に typealias を使用していましたが、新たに associatedtype で指定できるようになりました。

protocol P {
        associatedtype Ty
}

typealias キーワードは Swift 2.2 では許可されていますが、非推奨であり警告が発生します。
この警告は Swift 3 ではエラーになります。

詳細については Swift Evolution proposal SE-0011 を参照してください。(24159196)」


したがって以下のように修正する必要があります。

protocol Vector2D {
    associatedtype DataType
    var x : DataType { get set }
    var y : DataType { get set }
}



●10.5 プロトコルに適合する型の定義方法


・継承のあるクラス定義でSelfを使う

List10-18 において、「詳解Swift(3)〜構造体」で述べたように定数プロパティへの割り当ては一度のみとなったため、プロパティ latitude と longitude を定数として定義しているとエラーが出ます。

let latitude: Double = 0.0
let longitude: Double = 0.0
required init(lat:Double, lon:Double) {
        self.latitude = lat        // error: immutable value 'self.latitude' may only be initialized once
        // note: initial value already provided in 'let' declaration
        self.longitude = lon        // error: immutable value 'self.longitude' may only be initialized once
        // note: initial value already provided in 'let' declaration
}

したがってプロパティ latitude と longitude を変数にするか初期値を未設定にする必要があります。

var latitude: Double = 0.0
var longitude: Double = 0.0

またメソッド copy では、メタタイプ値からの初期化では明示的に「init」を参照しなければならないというエラーと、変数 nw が変更されないことから定数にすべきではないかと警告が出ますので修正する必要があります。

func copy() -> Self {
        var nw = self.dynamicType(lat:latitude, lon:longitude)
        // error: initializing from a metatype value must reference 'init' explicitly
        // warning: variable 'nw' was never mutated; consider changing to 'let' constant
        return nw
}


func copy() -> Self {
        let nw = self.dynamicType.init(lat:latitude, lon:longitude)
        return nw
}

List10-19 においても同様に、定数プロパティ name を定数から変数に、メソッド copy に .init を追加する必要があります。

class ViewPoint : GeoPoint {
    let name: String = ""
    required init(lat: Double, lon: Double) {
        self.name = "(none)"    // error: immutable value 'self.name' may only be initialized once
        // note: initial value already provided in 'let' declaration
        // note: change 'let' to 'var' to make it mutable
        super.init(lat: lat, lon: lon)
    }
    override func copy() -> Self {
        var nw = self.dynamicType(name:name, lat:latitude, lon:longitude)
        // error: initializing from a metatype value must reference 'init' explicitly
        // warning: variable 'nw' was never mutated; consider changing to 'let' constant
        return nw
    }


class ViewPoint : GeoPoint {
    var name: String = ""
    required init(lat: Double, lon: Double) {
        self.name = "(none)"
        super.init(lat: lat, lon: lon)
    }
    override func copy() -> Self {
        let nw = self.dynamicType.init(name:name, lat:latitude, lon:longitude)
        return nw
    }



Swift 1.2からSwift 2への移行 #cocoa_kansai

Qiita/Swift 2.2の新機能: SE-0011: 付属型を宣言するための typealias キーワードを associatedtype に置き換える

詳解 Swift 改訂版(Amazon)
 






Bose QuietComfort 20
0 Comments
Leave a comment
管理者にだけ表示を許可する
Top
0 Trackbacks
Top
Calendar
08 | 2017/09 | 10
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

Bose QuietComfort 20
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