Swift中的多个索引类型

时间:2015-11-01 19:49:50

标签: swift parameter-passing type-inference

在Swift(一种我还很新的语言)中,我尝试定义一个允许使用IntRange<Int>进行索引的类。例如:

var m = Matrix(rows: 10, cols: 10)
var v = m[1, 0..<10]

我能想到允许这个问题的两种方法是在Range类中添加一个扩展名:

extension Range {
  init(_ intValue:Element) {
    self.init(start: intValue, end: intValue.successor())
  }
}

或创建允许任何一种类型的枚举:

enum IndexType {
    case value(Int)
    case range(Range<Int>)

    init(_ v:Int) {
        self = .value(v)
    }

    init(_ r:Range<Int>) {
        self = .range(r)
    }
}

但是,两种解决方案都无法按预期工作,因为我仍需要手动指定类型。例如,给定函数:

func slice(indices:IndexType...) -> [Double] {
  // ...
}

我不能这样做:

slice(1, 3...4, 5)

但必须这样做:

slice(IndexType(1), IndexType(3...4), 5)

有没有办法在Swift中实现这一目标?我习惯使用c ++,它会自动进行类型推断,但同样不适用于Swift。

我发现的一个类似问题是: Swift Arrays of Multiple Types

但是,我真的想避免使用Any,因为我知道它应该是两种类型。

1 个答案:

答案 0 :(得分:1)

protocol MatrixIndex {
    var Matrix_range: Range<Int> { get }
}

extension Int : MatrixIndex {
    var Matrix_range: Range<Int> {
        get {
            return Range<Int>(start: self, end: self+1)
        }
    }
}

extension Range : MatrixIndex {
    var Matrix_range: Range<Int> {
        get {
            return Range<Int>(start: self.startIndex as! Int, end: self.endIndex as! Int)
        }
    }
}

class Matrix {
    subscript(row: MatrixIndex, column: MatrixIndex) -> () {
        get {
            print("getting \(row.Matrix_range) \(column.Matrix_range)")
        }

        set(newValue) {
            print("setting \(row.Matrix_range) \(column.Matrix_range)")
        }
    }
}