2016-02-05 110 views
0

類似的結構我有以下兩種結構:結合斯威夫特

struct Struct1 { 
    let name: String 
    let values: [Double] 

    func calculateValues() -> [Double] { 
    // Struct1 implementation 
    } 
} 

struct Struct2 { 
    let name: String 
    let symbol: String 
    let values: [Double] 

    func calculateValues() -> [Double] { 
    // Struct2 implementation 
    } 
} 

calculateValues()的實現是Struct1Struct2不同。

來自ObjectiveC我看到兩者之間有很多相似之處,它尖叫着繼承着我。但據我所知,這不適用於Swift中的結構。

我也試過typealias Struct2 = Struct1,但後來我不認爲我可以添加額外的屬性。

我可以把它保留原樣,但可能有一個快速的方式來「結合」兩者?

+3

繼承似乎是一個非常糟糕的解決方案只是爲了實現共享,甚至是屬性聲明。 – Sulthan

+1

爲什麼不讓他們上課?多態性是主要的OOP功能。 –

+0

@Sulthan:這就是我的想法,所以還有其他的選擇(除了使用已經回答過的課程或作文)。在這種情況下,協議會有所幫助嗎? – Koen

回答

3

如何使用組合?

struct Struct2 { 
    let struct1: Struct1 
    let symbol: String 

    func calculateValues() -> [Double] { 
    // Struct2 implementation 
    } 
} 
+1

經過在PlayGround中思考和修補了很多東西之後,我認爲在我的例子中前進的方向是使用這種Composite方法,並結合'Calculate''協議'。 – Koen

1

我主張可能會遷移到類作爲替代,取決於您的結構的實際實現(多少個常見的屬性和方法等)。從上面的例子看來,這兩個構造做了共享屬性;除了附加屬性symbol和方法calculateValue之外,都可以通過子類化第一個構造(如果遷移到類的使用)來添加。然而,如果兩個結構的實例從未實際上可互換使用,例如在外部功能(通常採用兩種方式中的任何一種)時,可能最好將兩者分開。

無論如何,因爲這個問題明確地涵蓋了結構:我認爲構圖是這裏的方式。然而,我將在下面添加一個鬆散相關的替代方法,以補充關於構建組合的現有答案。


如果你有,只有單一功能不同的各種非常相似的結構,你可以使用一個單一的結構來表示不同的實例的情況下,各種原結構進行了旨在覆蓋;用閉包替換函數。您可以讓閉包有一個默認值(比如說,代表calculateValuesStruct1以上),但可以選擇在初始化時與默認值不同的定義。最後,通過構造中的計算屬性訪問閉包。

共同的結構:

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]      */