簡體   English   中英

在Swift中將struct重構為枚舉

[英]Refactor struct as an enum in Swift

今天,有人對此代碼發表了評論,並建議使用enum會更好:

typealias PolicyType = (filename: String, text: String)

struct Policy {
  static let first = PolicyType(filename: "firstFile.txt", text: "text in first file")
  static let second = PolicyType(filename: "secondFile.txt", text: "text in second file")
  static let third = PolicyType(filename: "thirdFile.txt", text: "text in third file")
}

let thirdPolicyText = Policy.third.text

使用枚舉是否有更有效的內存且可維護的方法? 我的主要目標是可維護性。

以下是我想出的內容:

enum Policy: RawRepresentable {
  case one
  case two
  case three

  var rawValue: (filename: String, text: String) {
    switch self {
    case .one:
      return ("1", "policy 1 text")
    case .two:
      return ("2", "policy 2 text")
    case .three:
      return ("3", "policy 3 text")
    }
  }

  init?(rawValue: (filename: String, text: String)) {
    switch rawValue {
    case ("1", "policy 1 text"):
      self = .one
    case ("2", "policy 2 text"):
      self = .two
    case ("3", "policy 3 text"):
      self = .three
    default:
      return nil
    }
  }
}

至此,我已經弄清楚了如何使用structenum實現類似的功能。 如果有人回去更新該enumenum似乎需要更多維護,並且更容易出錯。 保羅·海加蒂(Paul Hegarty)表示,不會崩潰的行是您不編寫的行,並且enum路線看起來和感覺很麻煩。

struct相比, enum路由有存儲優勢嗎?

完成后,我希望能夠將Policy作為參數傳遞,如下所示:

func test(for policy: Policy) {
  print(policy.rawValue.filename)
  print(policy.rawValue.text)
}

test(for: Policy.first)

這是一種可能性。 這有點冗長,但是很迅速:

enum Policy {
    case one, two, three

    var filename: String {
        switch self {
        case .one: return "Policy 1 name"
        case .two: return "Policy 2 name"
        case .three: return "Policy 3 name"
        }
    }

    var text: String {
        switch self {
        case .one: return "Policy 1 text"
        case .two: return "Policy 2 text"
        case .three: return "Policy 3 text"
        }
    }
}

目前,Swift枚舉的問題在於它們僅限於RawValues。 我最近遇到了與您類似的情況,並且我也嘗試使用枚舉而不是結構。 我什至嘗試了一個命名元組。 但是,我最終使用了一個結構。

使用我能想到的一個枚舉的唯一改進就是簡單地用一個enum替換struct關鍵字:

enum Policy {
  static let first = PolicyType(filename: "firstFile.txt", text: "text in first file")
  static let second = PolicyType(filename: "secondFile.txt", text: "text in second file")
  static let third = PolicyType(filename: "thirdFile.txt", text: "text in third file")
}

沒有實例的枚舉是無法實例化的,因此開發人員只能使用定義的靜態策略類型。

像這樣的功能:

func cantBeCalled(policy: Policy) { }

無法從您的代碼中調用,因為無法構造(分配) Policy

不過,我將保留該結構,並將所有內容重新設計為一個類型:

struct Policy {
    static let first = Policy(filename: "firstFile.txt", text: "text in first file")
    static let second = Policy(filename: "secondFile.txt", text: "text in second file")
    static let third = Policy(filename: "thirdFile.txt", text: "text in third file")

    public let filename: String
    public let text: String

    private init(filename: String, text: String) {
        self.filename = filename
        self.text = text
    }
}

結構需要在問題域上更好地映射,因為您需要一個容納兩個屬性的容器。 當細節數量增加時,元組不擅長縮放,並且也更難操縱(例如,它們不符合協議)。

這種新的結構設計具有與上述枚舉相同的優點:不能“手動”構造策略,只有一組預定義的策略可用。 並帶來更多好處:只有一種類型,容器的語義更好,能夠在Policy類型上使用協議,沒有對屬性的模棱兩可的訪問(可以通過標簽或索引訪問帶標簽的元組的成員) )。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM