55406


次の2つのプロトコルの書き方は同じことを表現できていますか？ それとも違う意味ですか？

ソース1

[code]

    protocol Hogeable: AnyObject {}
    extension Hogeable where Self: UIViewController {}
    
[/code]

と

ソース2

[code]

    protocol Hogeable: UIViewController {}
    extension Hogeable {}
    
[/code]

ソース1の書き方をよく見るような気がしたのですが、どこかのSwfitのバージョンでソース2の書き方もできるようになったりしましたでしょうか？

上記のコードは空っぽですが、  
`Hogeable`の`extension`内は`UIViewController`であることが前提のソースコードを書かれていることを想定しています（`navigationController`にアクセスするとか)。


CC BY-SA 4.0
2019-05-31T08:41:55.557
55403
2019-06-01T00:07:02.377
2019-05-31T08:48:17.870
9008
9008
question
swift
次の2つのprotocolの書き方は同じことを表現できていますか？　それとも違う意味ですか？


自分自身ソース2みたいな書き方ができたっけ?とか思ってしまったのですが、こちらですね。

[Swift 5 Release Notes for Xcode
10.2](https://developer.apple.com/documentation/xcode_release_notes/xcode_10_2_release_notes/swift_5_release_notes_for_xcode_10_2)

[Resolved
Issues](https://developer.apple.com/documentation/xcode_release_notes/xcode_10_2_release_notes/swift_5_release_notes_for_xcode_10_2#3136868)

>   * Protocols can now constrain their conforming types to those that
> subclass a given class. Two equivalent forms are supported:
>

[code]

>     protocol MyView: UIView { /*...*/ }
>     protocol MyView where Self: UIView { /*...*/ }
>  
[/code]

>
> Swift 4.2 accepted the second form, but it wasn’t fully implemented  
>  and could sometimes crash at compile time or runtime. (SR-5581) (38077232)

Swift 4.2までは、上記2つ目の書き方は「エラーは出ないけどまともに動かなかった」と言うことだったのですが、Swift
5でそのバグが修正された際に、上記1個目と2個目の書き方は等価、と明確化されたようです。(実際には他のバージョンでも「エラーは出ない」ものはあるかも知れません。【追記】Xcode
9.4.1でも10.1でもダメだったんで、Swift 5より以前は構文的にエラーになっていたと思われます。)

と言うわけで、ご質問内の「ソース2」の書き方は、

[code]

    protocol Hogeable where Self: UIViewController {}
    extension Hogeable {}
    
[/code]

と等価と言うことになります。

ちなみに「ソース1」の書き方はSwift 4で、[Class and Subtype
existentials](https://github.com/apple/swift-
evolution/blob/master/proposals/0156-subclass-
existentials.md)が導入された折に旧来の`:class`と等価であると定められました。ですから、こちらと等価。

[code]

    protocol Hogeable: class {}
    extension Hogeable where Self: UIViewController {}
    
[/code]

* * *

従って、  
**_次の2つのプロトコルの書き方は同じことを表現できていますか？ それとも違う意味ですか？_**  
の答えは、

**違う意味です。**

と言うことになります。「ソース1」の方では、プロトコル`Hogeable`には、任意のクラスが適合することが出来ますが、「ソース2」の方は、`UIViewController`のサブクラスしか`Hogeable`に適合することが出来ません。

「ソース1」型の宣言

[code]

    protocol Hogeable: AnyObject {}
    extension Hogeable where Self: UIViewController {
        var testProperty: String {
            return "test"
        }
    }
    
    class MyClass: Hogeable {} //<- ここではエラーが出ない
    let myObj = MyClass()
    print(myObj.testProperty) //<- ここでエラーになる
    
[/code]

「ソース2」型の場合

[code]

    protocol Hogeable: UIViewController {}
    extension Hogeable {
        var testProperty: String {
            return "test"
        }
    }
    
    class MyClass: Hogeable {} //<- ここで既にエラー
    let myObj = MyClass()
    print(myObj.testProperty) //<- 当然ここもエラーだが、上のエラーのせいで無視されるかも
    
[/code]


CC BY-SA 4.0
2019-05-31T10:11:00.237
55406
2019-06-01T00:07:02.377
2019-06-01T00:07:02.377
13972
13972
55403
answer