【问题标题】:How do I declare the type of an array index in swift 4如何在swift 4中声明数组索引的类型
【发布时间】:2018-04-04 03:25:37
【问题描述】:

我正在尝试创建一个 2D 查找表,其中枚举表示 swift 4 中表的轴,例如:

enum ECT: Int {
  case cool = 0
  case normal
  case above_range
}

enum Load: Int {
  case idle = 0
  case cruise
  case wot
}

var timingRetard = [[Double?]](repeating: [nil,nil,nil], count 3)

(不,我不是在 Swift 中编写嵌入式 PCM 代码(那会很有趣!),但它是我尝试使用但尚未弄清楚语法的 swift 构造的一个简单示例)

如何使用枚举作为索引来分配和检索数组中的值,例如假设元素已经被创建

timingRetard[cool][idle] = 0.0
timingRetard[cool][cruise] = 0.0
timingRetard[cool][wot] = 0.0
timingRetard[above_range][wot] = -8.0
timingRetard[normal][cruise] = 0.0

在给定每个轴的枚举数的情况下,如何在初始化数组后声明 Swift 数组的索引类型只能由枚举类型访问?我想我可以将 timingRetard 添加到一个结构中并声明一个下标方法来将索引限制为枚举类型,但也没有让它工作。

【问题讨论】:

    标签: arrays swift enums indices


    【解决方案1】:

    实现的一种方法是覆盖结构中的下标方法。 here 解释得更好。我使用链接中提到的示例以这种方式解决您的问题:

    enum ECT: Int{
        case cool = 0
        case normal
        case above_range
    }
    
    enum Load: Int {
        case idle = 0
        case cruise
        case wot
    }
    
    struct TimingRetard2D {
        let rows: Int, cols: Int
        private(set) var array:[Double?]
    
        init(rows: Int, cols: Int, repeating:Double?) {
            self.rows = rows
            self.cols = cols
            array = Array(repeating: repeating, count: rows * cols)
        }
    
        private func indexIsValid(row: Int, col: Int) -> Bool {
            return row >= 0 && row < rows && col >= 0 && col < cols
        }
    
        subscript(row: ECT, col: Load) -> Double? {
            get {
                assert(indexIsValid(row: row.rawValue, col: col.rawValue), "Index out of range")
                return array[(row.rawValue * cols) + col.rawValue]
            }
            set {
                assert(indexIsValid(row: row.rawValue, col: col.rawValue), "Index out of range")
                array[(row.rawValue * cols) + col.rawValue] = newValue
            }
        }
    }
    
    var timingRetard = TimingRetard2D.init(rows: 3, cols: 3, repeating: nil)
    timingRetard[.cool, .idle] = 0.0
    timingRetard[.cool, .cruise] = 0.0
    timingRetard[.cool, .wot] = 0.0
    timingRetard[.above_range, .wot] = -8.0
    timingRetard[.normal, .cruise] = 0.0
    print(timingRetard.array)
    

    输出:

    [可选(0.0),可选(0.0),可选(0.0),无,可选(0.0),无,无,无,可选(-8.0)]

    【讨论】:

    • 谢谢,确实有效。但是,我对其进行了一些更新,以模拟真正快速的数组数组,以防它需要提取或更新整行。见下文
    【解决方案2】:

    对 Puneet 解决方案的小幅更新,它允许数组数组而不是计算偏移量到一维数组中:

    enum ECT: Int{
        case cool = 0
        case normal
        case above_range
    }
    
    enum Load: Int {
        case idle = 0
        case cruise
        case wot
    }
    
    struct TimingRetard2D {
        let rows: Int, cols: Int
        private(set) var array:[[Double?]]
    
        init(rows: Int, cols: Int, repeating:Double?) {
            self.rows = rows
            self.cols = cols
            let initRow = Array(repeating: repeating, count: cols)
            array = Array(repeating: initRow, count: rows)
        }
    
        private func indexIsValid(row: Int, col: Int) -> Bool {
            return row >= 0 && row < rows && col >= 0 && col < cols
        }
    
        subscript(row: ECT, col: Load) -> Double? {
            get {
                assert(indexIsValid(row: row.rawValue, col: col.rawValue), "Index out of range")
                return array[row.rawValue][col.rawValue]
            }
            set {
                assert(indexIsValid(row: row.rawValue, col: col.rawValue), "Index out of range")
                array[row.rawValue][col.rawValue] = newValue
            }
        }
    }
    
    var timingRetard = TimingRetard2D.init(rows: 3, cols: 3, repeating: nil)
    timingRetard[.cool, .idle] = 0.0
    timingRetard[.cool, .cruise] = 0.0
    timingRetard[.cool, .wot] = 0.0
    timingRetard[.above_range, .wot] = -8.0
    timingRetard[.normal, .cruise] = 0.0
    print(timingRetard.array)
    

    但是,还有没有让结构的使用者也使用二维数组语法?例如计时延迟[.cool][.wot]

    【讨论】:

      【解决方案3】:

      你可以这样写:

      extension Array where Element == Double? {
          subscript(load: Load) -> Element {
              get {
                  return self[load.rawValue]
              }
              set {
                  self[load.rawValue] = newValue
              }
          }
      }
      
      extension Array where Element == [Double?] {
          subscript(ect: ECT) -> Element {
              get {
                  return self[ect.rawValue]
              }
              set {
                  self[ect.rawValue] = newValue
              }
          }
      }
      
      
      var timingRetard = [[Double?]](repeating: [nil,nil,nil], count: 3)
      
      timingRetard[.cool][.idle] = 0.0
      timingRetard[.cool][.cruise] = 0.0
      timingRetard[.cool][.wot] = 0.0
      timingRetard[.above_range][.wot] = -8.0
      timingRetard[.normal][.cruise] = 0.0
      

      但是,扩展您的TimingRetard2D 似乎更好。

      【讨论】:

        猜你喜欢
        • 2015-10-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-05-01
        • 2018-04-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多