swift – 将协议和符合类(!)实例作为参数的函数
我试图找出如何定义一个具有以下功能的函数
两个参数: >协议. 例如,给定 protocol P { } class C : P { } // Class,conforming to P class D { } // Class,not conforming to P struct E: P { } // Struct,conforming to P 这应该编译: register(P.self,obj: C()) // (1) 但这些不应该编译: register(P.self,obj: D()) // (2) D does not conform to P register(P.self,obj: E()) // (3) E is not a class 如果我们放弃第二个参数是类实例的条件,这很容易: func register<T>(proto: T.Type,obj: T) { // ... } 但这也会接受(3)中的struct(值类型). func register<T: AnyObject>(proto: T.Type,obj: T) { // ... } 但是,(1),(2),(3)中的任何一个都不再编译,例如 register(P.self,obj: C()) // (1) // error: cannot invoke 'register' with an argument list of type '(P.Protocol,obj: C)' 我假设编译器错误的原因与中的相同 另一次失败的尝试是 func register<T>(proto: T.Type,obj: protocol<T,AnyObject>) { } // error: non-protocol type 'T' cannot be used within 'protocol<...>' 可行的替代方案是作为参数的函数 >类协议. 这里的问题是如何限制第一个参数 背景:我最近偶然发现了 public class NotificationCenter { public static func register<T>(protocolType: T.Type,observer: T) { guard let object = observer as? AnyObject else { fatalError("expecting reference type but found value type: (observer)") } // ... } // ... } 然后观察者被存储为弱引用,这就是他们的原因 我错过了一些简单/明显的东西吗?
你无法直接做你想做的事.它与引用类型无关,这是因为任何约束都会使T存在,因此当您引用协议的元类型P.self:P.Protocol和采用者C时,不可能在调用站点满足它们.特殊情况,当T不受约束,允许它首先工作.
到目前为止,更常见的情况是约束T:P并且需要P:class,因为对于任意协议的元类型,你唯一可以做的就是将名称转换为字符串.它恰好在这种狭隘的情况下很有用,但就是这样;签名也可以注册< T>(proto:Any.Type,obj:T),它将做的所有好处. 从理论上讲,Swift可以支持约束元类型,ala寄存器< T:AnyObject,U:AnyProtocol其中T.Type:U>(proto:U,obj:T)但我怀疑它在许多情况下会有用. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |