结合Swift中的类似结构

时间:2016-02-05 12:57:33

标签: swift struct

我有以下两种结构:

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()Struct1的{​​{1}}实施方式不同。

来自Struct2我发现两者之间有很多相似之处,它尖叫着继承我。但据我所知,这对Swift中的结构不起作用。

我也试过了ObjectiveC,但我觉得我不能添加额外的属性。

我可以保持原样,但可能有一种Swift的方式以某种方式“结合”两者?

2 个答案:

答案 0 :(得分:3)

使用作文怎么样?

struct Struct2 {
   let struct1: Struct1
   let symbol: String

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

答案 1 :(得分:1)

我会提倡可能迁移到类作为替代,取决于结构的实际实现(有多少常见属性和方法等)。从上面的例子可以看出,两个构造共享属性;除了附加属性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]                      */