将Swift Generic类型与协议一起使用



我试图将通用类型与协议使用:

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()

并收到编译器错误:错误:"某些协议"无法转换为" 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()

为什么我不能在通用类中使用协议的nobjject?

swift协议是不完整的类型,这意味着您不能在诸如通用参数之类的地方使用它们,因为编译器需要了解整个类型的详细信息,因此它可以分配正确的内存布局。

如果您使其成为通用:

仍然可以使用您的createWeak功能
func createWeak<T: SomeProtocol>(object: T) -> Weak<T> {
    return Weak<T>(value: object)
}

上面的代码工作是因为编译器将在编译时间生成一个映射到您通过的混凝土类型的函数。

更好的是,您可以使初始化器通用,然后将Weak转换为struct(值类型比参考的优选(:

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

您可以使用它而不是免费功能:

let weakRef = Weak(temp)

最新更新