我主張可能會遷移到類作爲替代,取決於您的結構的實際實現(多少個常見的屬性和方法等)。從上面的例子看來,這兩個構造做了共享屬性;除了附加屬性symbol
和方法calculateValue
之外,都可以通過子類化第一個構造(如果遷移到類的使用)來添加。然而,如果兩個結構的實例從未實際上可互換使用,例如在外部功能(通常採用兩種方式中的任何一種)時,可能最好將兩者分開。
無論如何,因爲這個問題明確地涵蓋了結構:我認爲構圖是這裏的方式。然而,我將在下面添加一個鬆散相關的替代方法,以補充關於構建組合的現有答案。
如果你有,只有單一功能不同的各種非常相似的結構,你可以使用一個單一的結構來表示不同的實例的情況下,各種原結構進行了旨在覆蓋;用閉包替換函數。您可以讓閉包有一個默認值(比如說,代表calculateValues
爲Struct1
以上),但可以選擇在初始化時與默認值不同的定義。最後,通過構造中的計算屬性訪問閉包。
共同的結構:
struct MyStruct {
let name: String
let symbol: String?
let values: [Double]
private let internalCalculateValues : ([Double], String?) -> [Double]
var calculateValues: [Double] {
return internalCalculateValues(values, symbol)
}
/* put default implementation of internalCalculateValues in init signature */
init(name: String, values: [Double], symbol: String? = nil,
calculateValues: ([Double], String?) -> [Double] = {
// default implementation: dont make use of symbol
return $0.0.map{ 2*$0 } }
) {
self.name = name
self.values = values
self.symbol = symbol
self.internalCalculateValues = calculateValues
}
}
用法示例:
/* use default calculateValues */
let s1 = MyStruct(name: "foo", values: [1.5, 3.0, 4.5])
print(s1.calculateValues) // [3.0, 6.0, 9.0]
/* use custom calculateValues */
let s2 = MyStruct(name: "foo", values: [1.5, 3.0, 4.5]) {
return $0.0.filter{ $0 > 2.5 }
}
print(s2.calculateValues) // [3.0, 4.5]
/* use custom calculateValues and make use also of 'symbol'
parameter in the closure */
let s3 = MyStruct(name: "foo", values: [1.5, 3.0, 4.5], symbol: "^2") {
print("Operated on values in array by: .\($0.1 ?? "")")
return $0.0.map{ pow($0,2) }
}
print(s3.calculateValues)
/* Operated on values in array by: .^2
[2.25, 9.0, 20.25] */
繼承似乎是一個非常糟糕的解決方案只是爲了實現共享,甚至是屬性聲明。 – Sulthan
爲什麼不讓他們上課?多態性是主要的OOP功能。 –
@Sulthan:這就是我的想法,所以還有其他的選擇(除了使用已經回答過的課程或作文)。在這種情況下,協議會有所幫助嗎? – Koen