4

我在尝试将泛型类型要求限制为仅引用类型时遇到问题。这是一些示例代码:

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

这是泛型的限制吗?将协议标记为类就足以对该协议进行弱引用,泛型中是否没有等效项?

4

2 回答 2

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 。略读它我没有发现任何与您的用例直接相关的内容,但它相当具体,因此它可能不包含在文档的参数中。

于 2016-12-01T00:56:49.707 回答
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)

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

于 2016-12-01T15:37:28.373 回答