不像在Objective-C,你不能定義純斯威夫特任擇議定書要求classes/structs
財產。符合協議的類型必須採用指定的所有要求。
允許可選屬性需求的一種潛在方式是將它們定義爲可選項,默認實現的計算屬性僅返回nil
。
protocol Nameable {
var name : String? { get }
var fullName : String? { get }
var nickname : String? { get }
}
extension Nameable {
var name : String? { return nil }
var fullName : String? { return nil }
var nickname : String? { return nil }
}
struct Person : Nameable {
// Person now has the option not to implement the protocol requirements,
// as they have default implementations that return nil
// What's cool is you can implement the optional typed property requirements with
// non-optional properties – as this doesn't break the contract with the protocol.
var name : String
}
let p = Person(name: "Allan")
print(p.name) // Allan
但是這樣做的缺點的方法是,你可能污染與他們沒有實現(在這種情況下fullName
& nickName
)性能符合類型。
因此,如果它使一個類型有這些特性沒有邏輯感(比如你想以符合City
到Nameable
- 但城市沒有(真正)有暱稱),你不應該是符合Nameable
。
如您所說,更靈活的解決方案將是定義多個協議以定義這些要求。這樣,類型可以精確選擇他們想要實現的要求。
protocol Nameable {
var name : String { get }
}
protocol FullNameable {
var fullName : String { get }
}
protocol NickNameable {
// Even types that conform to NickNameable may have instances without nicknames.
var nickname : String? { get }
}
// A City only needs a name, not a fullname or nickname
struct City : Nameable {
var name : String
}
let london = City(name: "London")
// Person can have a name, full-name or nickname
struct Person : Nameable, FullNameable, NickNameable {
var name : String
var fullName: String
var nickname: String?
}
let allan = Person(name: "Allan", fullName: "Allan Doe", nickname: "Al")
你甚至可以使用protocol composition爲了定義一個typealias
代表所有這三種協議的便利,例如:
typealias CombinedNameable = Nameable & FullNameable & NickNameable
struct Person : CombinedNameable {
var name : String
var fullName: String
var nickname: String?
}
我不知道協議組成的,感謝分享該鏈接。有趣的是,蘋果在名爲'Named'的示例中調用了協議,而Swift API指導原則中聲明'描述功能的協議應該使用後綴名稱,可以是ible或ing(例如Equatable,ProgressReporting)。' – Koen
@Koen Happy to幫助:)關於協議命名指南,國際海事組織都提供'命名'和'命名'是可以接受的,因爲它們都直接描述了一種能力。我通常想到的方式是它應該適合句子「An X is Y」,其中X是符合類型,Y是協議(例如「一個人是可命名/命名的」)。儘管按我自己的邏輯走,「CombinedNameable」並不是一個好選擇(我打算稱它爲「FullyNameable」,但與「FullNameable」IMO太接近了)。 – Hamish