2017-12-10 25 views
2

프로토콜을 일반 매개 변수로 사용하는 클래스 (ProtocolPrinter)를 만들려고합니다. 왜 컴파일되지 않을까요?스위프트 프로토콜을 일반 매개 변수로 사용

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을 지정할 필요가 있음을 밝혀 그 다른 모든 프로토콜 (또한 @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!