使用swift Generic Types和协议

时间:2018-02-27 17:56:58

标签: swift generics swift4

我尝试使用带协议的泛型类型:

class Weak<T: AnyObject> {
    weak var value: AnyObject?
    init (value: AnyObject) {
        self.value = value
    }
}

protocol SomeProtocol: AnyObject {
    func doSomething()
}

func createWeak(object: SomeProtocol) -> Weak<SomeProtocol> {
    return Weak<SomeProtocol>(value: object)
}

class SomeClass: SomeProtocol {
    func doSomething() {
        print("Some 2")
    }
}

let temp =  SomeClass()
let weakObject = createWeak(object: temp)
weakObject.value?.doSomething()

得到了编译器错误: 错误:'SomeProtocol'无法转换为'AnyObject'     返回弱(值:对象)

但没有AnyObject约束,它可以正常工作

class Weak<T> {
var value: T?
    init (value: T) {
        self.value = value
    }
}

protocol Protocol {
    func doSomething()
}

class Class: Protocol {
    func doSomething() {
        print("This is class")
    }
}

func createWeak(object: Protocol) -> Weak<Protocol> {
    return Weak(value: object)
}

let temp =  Class()
let weakObject = createWeak(object: temp)
weakObject.value?.doSomething()

为什么我不能在泛型类中使用从AnyObject继承的协议?

1 个答案:

答案 0 :(得分:2)

Swift协议是不完整的类型,这意味着你不能在泛型参数这样的地方使用它们,因为编译器需要知道整个类型的细节,以便它可以分配适当的内存布局。

如果您将createWeak功能设为通用,则仍然可以使用它:

func createWeak<T: SomeProtocol>(object: T) -> Weak<T> {
    return Weak<T>(value: object)
}

上面的代码是有效的,因为编译器会在编译时生成一个映射到您传递的具体类型的函数。

更好的是,您可以使初始化程序通用,并将Weak转换为结构(值类型优先于Swift而不是引用):

struct Weak<T: AnyObject> {
    weak var value: T?

    init(_ value: T) {
        self.value = value
    }
}

你可以使用它而不是自由函数:

let weakRef = Weak(temp)