2016-11-30 92 views
2

我在试图限制泛型类型的要求,只是引用类型的问题。下面是一些示例代码:斯威夫特通用引用类型

class WeakHolder<Element: AnyObject> { 
    weak var element: Element? 

    init(element: Element) { 
     self.element = element 
    } 
} 

protocol Animal: class { } 

class Dog: Animal { } 

let dog: Animal = Dog() 
let holder = WeakHolder<Animal>(element: dog) // Error: Using "Animal" as a concrete type conforming to protocol 'AnyObject' is not supported. 

如果我改变通用要求<Element: class>,我得到的错误class constraint can only appear on protocol declarations

这是仿制药的限制?将协议标记为类足以对该协议有一个弱引用,那么泛型中没有等价物吗?

+0

狗是不是AnyObject因为狗是根据我的经验,小的协议 –

+0

这可能是仿制药限制SWIFT 2.3。您可以通过使用类而不是协议来修复此问题 –

+0

我需要在我的实施中使用协议。 – Mark

回答

0

简单的答案是,你不能有一个泛型类型,它是一个协议。

写出语法清楚它是如何工作: class/struct GenericType<TypeName: TypeConstraints> {}

let thing = GenericType<Type>() where Type is a class or struct that adheres to any constraints

一个协议,要求采用类别为一类指采用者类,但协议本身仍不一种。

这是可能的仿制药可能会在某个时候支持协议,但它需要改变要么协议或仿制药的一般方法。尽管你的具体例子可能在幕后工作量较小,所以有可能在某些时候实施。

,如果你想看到他们要去的方向,您可以看看The Generics Manifesto。浏览它我没有发现任何与你的用例直接相关的东西,但它相当具体,所以它可能不包含在文档的参数中。

+0

啊,广义的类约束正是我正在寻找的。很高兴知道它正在考虑未来版本的Swift。 – Mark

0

另一种解决方案是,在我的特定情况下的工作如下:

class WeakHolder<Element: AnyObject> { 
    weak var element: Element? 

    init(element: Element) { 
     self.element = element 
    } 
} 

protocol Animal: class { } 

class Dog: Animal { } 

let dog: Animal = Dog() 
let holder = WeakHolder<AnyObject>(element: dog as AnyObject) 

当访问元件,我只需要执行向下转换回我的协议。当然,在使用这个类的值类型时,我会失去编译时的安全性,但在我的情况下这不是问题。