2017-07-06 57 views
0

我有一個結構與2個變量。這個結構具有變異函數,但是在這個函數中我需要檢查變異的變量。爲此,我使用獨立的類'靜態函數與複雜的邏輯。這個類適用於不同的結構,所以對於DRY而言,我不能在所有這些結構中表示這種邏輯。突變func與外部檢測哪個變量變異

的問題是,我不知道如何從這個單獨的類接收相同結構的變化,所以沒有結構的變量發生變異。我想,我錯過了一些斯威夫特的知識,因爲我敢肯定,這是可能的,沒有重複的邏輯。

代碼來表示它在遊樂場:

struct SomeStruct { 
    var a = "a" 
    var b = "b" 

    mutating func mutateString(to newString: String) { 
     var varToMutate = VariableDetector.whichVarToMutate(a, b) 
     varToMutate = newString 

     // prints to represent question 
     print("varToMutate: \(varToMutate)") 
     print("a: \(a)") 
     print("b: \(b)") 
    } 
} 

class VariableDetector { 
    static func whichVarToMutate(_ first: String, _ second: String) -> String { 
     var firstOrSecondString = "" 

     // simple logic to represent question, in real case it is far more complex 
     if first == "a" { 
      firstOrSecondString = first 
     } else { 
      firstOrSecondString = second 
     } 

     return firstOrSecondString 
    } 
} 

var someStruct = SomeStruct() 
someStruct.mutateString(to: "c") 

此代碼生成:

varToMutate: c 
a: a 
b: b 

是的,它可以與解決:

if varToMutate == a { 
    a = newString 
} else if varToMutate == b { 
    b = newString 
} 

但我想解決這個問題以更優雅的方式:)

感謝您的幫助!

+1

在一個側面說明,這不是很習慣使用類只定義靜態方法。要麼你可以讓這些方法爲功能與狹窄的訪問說明符(如'fileprivate'或'internal',從而限制全局命名空間的人口),也可以使用小寫的'enum'(保護,防止意外實例) – Alexander

回答

1

在斯威夫特4,這可以通過返回從whichVarToMutate一個KeyPath來完成。 KeyPath然後可以用於訪問有問題的實例,並改變它表示的屬性。

在夫特3,有2種方法我能想到的:

  1. 傳遞一個增變閉合到判定方法,它穿出適當變種突變作爲inout PARAM,然後具有封閉身體突變它。
  2. 定義包含這些變量(您所述多類型之間共享)的協議,使這些類型一致的,並提供在限定的方法,這將適用於所有這些協議的擴展。這是我會用這種方法,即使是在斯威夫特4:

    struct SomeStruct { 
        var a = "a" 
        var b = "b" 
    } 
    
    protocol Mutable { // TODO: Rename me appropriately 
        var a: String { get set } 
        var b: String { get set } 
    } 
    
    extension SomeStruct: Mutable {} 
    
    extension Mutable { 
        mutating func changeAppropriateVar(to newValue: String) -> Void { 
         // simple logic to represent question, in real case it is far more complex 
         let someCondition = true 
    
         if someCondition { 
          print("Setting `a` to \(newValue)") 
          a = newValue 
         } 
         else { 
          print("Setting `b` to \(newValue)") 
          b = newValue 
         } 
        } 
    } 
    
    var s = SomeStruct() 
    s.changeAppropriateVar(to: "foo") 
    
+0

亞歷山大,它很棒:)感謝您的回答和評論! –

+0

@PeterTretyakov任何時候你最終都會提取這樣的公共邏輯,想一想「我可以用協議和擴展提供默認實現嗎?」。大多數時候是肯定的。 – Alexander

+0

脆弱的方式:)其實我認爲,它可以通過協議來解決,但協議概念對我來說還不是很清楚。附:如果有人發現了這個問題,看看這個視頻從WWDC2015關於面向協議編程https://developer.apple.com/videos/play/wwdc2015/408/ –

1

除非ab是一個類的實例,否則varToMutate將只是一個副本,因爲除了一個類之外,所有其他類都是Swift中的值類型。也許試試UnsafeMutablePointer<T>