Swift 协议中的静态类型属性

Statically typed properties in Swift protocols

我正在尝试对我的应用程序中的模型层使用面向协议的编程

我已经开始定义两个 protocol

protocol ParseConvertible {
    func toParseObject() -> PFObject?
}

protocol HealthKitInitializable {
    init?(sample: HKSample)
}

在实现第一个符合两者的模型后,我注意到另一个模型基本相似,所以我想用新模型创建协议继承

protocol BasicModel: HealthKitInitializable, ParseConvertible {

    var value: AnyObject { get set }

}

A 你可以看到这个 protocol 还有一个东西是 value 但我希望这个值与类型无关......现在我有使用 Double 的模型但谁知道将来会出现什么。如果我将其与 AnyObject 一起保留,我将被判强制转换我想使用它的所有内容,如果我将其声明为 Double 则称其为 BasicModel 是没有意义的,而是 BasicDoubleModel 或类似的。

你有一些关于如何实现这一点的提示吗?或者也许我试图以错误的方式解决这个问题?

您可能想定义一个带有 "associated type" 的协议, 这与泛型类型大致相似。 来自 Swift 书中的 "Associated Types"

When defining a protocol, it is sometimes useful to declare one or more associated types as part of the protocol’s definition. An associated type gives a placeholder name (or alias) to a type that is used as part of the protocol. The actual type to use for that associated type is not specified until the protocol is adopted. Associated types are specified with the typealias keyword.

你的情况:

protocol BasicModel: HealthKitInitializable, ParseConvertible {
    typealias ValueType
    var value: ValueType { get set }
}

然后类用不同的类型为value属性即可 符合协议:

class A : BasicModel {
    var value : Int
    func toParseObject() -> PFObject? { ... }
    required init?(sample: HKSample) { ... }
}

class B : BasicModel {
    var value : Double
    func toParseObject() -> PFObject? { ... }
    required init?(sample: HKSample) { ... }
}

对于 Swift 2.2/Xcode 7.3 及更高版本,将 typealias 替换为 协议定义 associatedtype.