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

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



CHAPTER 10 プロトコル



●10.2 プロトコルと型


・オプション項目のあるプロトコルを宣言する

プロトコル PersonalData の宣言において、オプション項目である変数 bloodtype と関数 age でエラーが出ます。

optional var bloodtype: String { get }    // error: 'optional' requirements are an Objective-C compatibility feature; add '@objc'
optional func age() -> Int    // error: 'optional' requirements are an Objective-C compatibility feature; add '@objc'

Qiita/Swift変更履歴早見表」によると、Swift 3 でプロトコルの optional 宣言は @objc optional に変更されたようです。

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

@objc optional var bloodtype: String { get }
@objc optional func age() -> Int


・プロトコルの使用例

List10-5 において、関数 sayHelloTo() の if-let 文でエラーが出ます。

if let w = p as? HealthInfo where self.sex == w.sex {    // Expected ',' joining parts of a multi-clause condition

これは「詳解Swift改訂版(04)〜オプショナル」の「4.2 オプショナル束縛構文/if-let 文」で説明したように、Swift 3 から条件句は "where" ではなく "," で区切るように変更されたためです。

if let w = p as? HealthInfo, self.sex == w.sex {

if-case 文の場合も同様です。



●10.3 プロトコルと付属型


・ネスト型とプロトコル

List10-6 において、typealias による付属型の宣言で警告が出るようになりました。

typealias Element    // Typealias is missing an assigned type; use 'associatedtype' to define an associated type requirement

これは「詳解Swift(10)〜プロトコル」で説明したように、typealias の代わりに associatedtype を使うように変更されたためです。

したがって付属型の宣言は以下のように修正する必要があります。

associatedtype Element


・付属型が適合するプロトコルを指定

List10-8 において、付属型へのプロトコルの指定でエラーが出るようになりました。

associatedtype Element: IntegerType    // error: 'IntegerType' has been renamed to 'Integer'

プロトコル InteferType は Integer に改名されたようなので修正します。

associatedtype Element: Integer


・付属型の制約を継承する

List10-9 において、上記と同様にプロトコル UnsignedIntegerType は UnsignedInteger に改名されています。

associatedtype Element: UnsignedIntegerType    // error: 'UnsignedIntegerType' has been renamed to 'UnsignedInteger'

associatedtype Element: UnsignedInteger



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


・プロトコル ForwardIndexType

List10-13 において、プロトコル ForwardIndexType を継承しようとするとエラーが出ます。

enum WeekDay: Int, ForwardIndexType {    // error: 'ForwardIndexType' has been renamed to 'Comparable'

Swift の標準ライブラリ(「Apple Developer Documentation/Swift Standard Library」参照)を見ても ForwardIndexType やそれに類するプロトコルが見当たらないので廃止されたと思われます。

エラーメッセージではプロトコル Comparable に改名されたとありますが、Comaparable のプロトコル要件には(比較)演算子関数しかなく関数 successor() のような関数がありません。

また「詳解Swift改訂版(05)〜基本的なデータ型」の「5.1 整数と実数/範囲型と区間型」の表にあるように、Comparable は区間型と範囲型の両方で採用されていますが、範囲型のみプロトコル Strideable が採用されているので Strideable を継承する必要があると思われます。

プロトコル Strideable の定義(概要)は以下の通りです。

public protocol Strideable : Comparable {
    associatedtype Stride : SignedNumber
    public func distance(to other: Self) -> Self.Stride
    public func advanced(by n: Self.Stride) -> Self
}

Strideable は Comparable を継承し、要件としてインスタンスメソッド distance(to:Self)advanced(by: Self.Stride) を実装する必要があります。
(「Qiita/Swift で Strideable な独自タイプを実装してみる」参照)

enum WeekDay: Int, Strideable {
    case Sun, Mon, Tue, Wed, Thu, Fri, Sat
   
    func distance(to other: WeekDay) -> Int {
        return other.rawValue
    }
   
    func advanced(by n: Int) -> WeekDay {
        return WeekDay(rawValue: (self.rawValue + n) % 7)!
    }

}

プロトコル ForwardIndexType の関数 successor が不要なことはもちろん、Swift 2.2 までの不可解な範囲型 Range が Swift 3 で半開区間型の CountableRange と閉区間型の CountableClosedRange に変更されたので _dummy という要素も不要です。

ただしプロトコル Comparable の要件である比較演算子の定義(List10-10 の関数 <() )は必須です。

なお、型を指定せずに範囲演算子を用いると範囲型になるので、区間型にするには型を指定する必要があります。
(閉区間型も同様)

let wd1 = WeekDay.Sun ..< .Wed
type(of: wd1)    // CountableRange<WeekDay>.Type

let wd2: Range = WeekDay.Mon ..< .Thu
type(of: wd2)    // Range<WeekDay>.Type


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

List10-14 において、クラス GeoPoint の関数 copy() でプロパティ dynamicType が用いられていますが、「詳解Swift改訂版(08)〜クラスと継承」の「8.1 クラス定義/継承とメソッド呼び出し」で説明したように dynamicType は廃止されて関数 type(of:) に変更されたので修正する必要があります。

let nw = self.dynamicType.init(lat:latitude, lon:longitude)    // '.dynamicType' is deprecated. Use 'type(of:...)' instead

let nw = type(of: self).init(lat:latitude, lon:longitude)



Qiita/Swift変更履歴早見表

Qiita/Swift で Strideable な独自タイプを実装してみる

詳解Swift 第3版(Amazon)
 






QuietControl 30 wireless headphones
0 Comments
Leave a comment
管理者にだけ表示を許可する
Top
0 Trackbacks
Top
Calendar
04 | 2017/05 | 06
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 31 - - -
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