2015-11-01 81 views
0

在Swift(一种我仍然比较陌生的语言)中,我试图定义一个允许使用IntRange<Int>索引的类。例如:Swift中的多种索引类型

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

两种方式我能想到让这个问题的是,要么添加一个扩展范围类:

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) 

是否有做到这一点的方式迅速?我习惯于C++,它会自动进行类型推断,但是它似乎不适用于Swift。

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

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

+0

你见过下标吗? –

+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)") 
     } 
    } 
} 
+0

真棒,看起来像它的作品。谢谢!一个小问题,返回'()似乎使'set'不能正常工作,但可以通过将其更改为合理的返回类型来修复。 –