2017-12-10 21 views
2

プロトコルを汎用パラメータとして使用するクラス(ProtocolPrinter)を作成しようとしています。なぜこれはコンパイルされませんか?クラスへの汎用パラメータとしてのSwiftプロトコル

import Foundation 

@objc protocol MyProtocol { 
    func foo() 
} 

class MyConformingClass: MyProtocol { 
    func foo() { 
     print("Foo!") 
    } 
} 

class ProtocolPrinter<T: Protocol> { 
    func printT() { 
     print("T: \(T.self)") 
    } 

    func dosomethingWithObject(_ object: T) { 
     if let object = object as? MyProtocol { 
      object.foo() 
     } else { 
      print("I don't know what object this is: \(object).") 
     } 
    } 
} 

let x = MyConformingClass() 
x.foo() // Foo! 

let myProtocolMeta: Protocol = MyProtocol.self // No error. 

ProtocolPrinter<MyProtocol>()      // 'ProtocolPrinter' requires that 'MyProtocol' inherit from 'Protocol' 
ProtocolPrinter<MyProtocol.self>()     // (treats "<" and ">" as operators) 
ProtocolPrinter<MyProtocol.Type>()     // 'ProtocolPrinter' requires that 'MyProtocol.Type' inherit from 'Protocol' 
ProtocolPrinter<MyProtocol.Type.self>()    // (treats "<" and ">" as operators) 
ProtocolPrinter<MyProtocol.Protocol>()    // type 'MyProtocol.Protocol' does not confor 
ProtocolPrinter<MyProtocol.Protocol.self>()   // (treats "<" and ">" as operators) 
ProtocolPrinter<MyProtocol.Protocol.Type>()   // type 'MyProtocol.Protocol.Type' does not conform to protocol 'MyProtocol' 
ProtocolPrinter<MyProtocol.Protocol.Type.self>()  // (treats "<" and ">" as operators) 
ProtocolPrinter<MyProtocol.Protocol.Protocol>()  // cannot use 'Protocol' with non-protocol type 'MyProtocol.Protocol' 
ProtocolPrinter<MyProtocol.Protocol.Protocol.Type>() // cannot use 'Protocol' with non-protocol type 'MyProtocol.Protocol' 
+0

1 'は何ですかプロトコル 'タイプ? 2. ProtocolPrinterは 'Protocol'に準拠したもので動作します。あなたは 'class ProtocolPrinter 'を持っていることでそれを要求しました。しかし、 'MyProtocol'は' Protocol'に従っていません – Honey

+0

'MyProtocol.self'はクラスである' Protocol'に準拠しています。これはすべての '@ objc'プロトコルに当てはまります。さらに多くのテストケースで私の答えを更新しました。 – Coder256

答えて

0

それはあなたが、たとえば、(も@objc protocol sでなければなりません)あなたの他のプロトコルの全てが準拠単一@objc protocolを指定するために必要なすべてのことが判明:

import Foundation 

@objc protocol SuperProtocol {} 
@objc protocol MyProtocol: SuperProtocol { 
    func foo() 
} 

class MyConformingClass: MyProtocol { 
    func foo() { 
     print("Foo!") 
    } 
} 

class ProtocolPrinter<T: SuperProtocol> { 
    func printT() { 
     print("T: \(T.self)") 
    } 

    func dosomethingWithObject(_ object: T) { 
     if let object = object as? MyProtocol { 
      object.foo() 
     } else { 
      print("I don't know what object this is: \(object).") 
     } 
    } 
} 

let x = MyConformingClass() 
x.foo() // Foo! 
MyProtocol.Protocol.self 
let myProtocolMeta: Protocol = MyProtocol.self 

ProtocolPrinter<MyProtocol>().dosomethingWithObject(MyConformingClass()) // Foo! 
関連する問題