按下标访问元组

时间:2015-06-14 15:10:32

标签: swift tuples

我们说我有这段代码:

let tuples = ("1", 2, "3", "4", "5", "6", "7", false)

func tableView(tableView:NSTableView, viewForTableColumn tableColumn:NSTableColumn?, row:Int) -> NSView?
{
    let valueForView = tuples[row]
}

有没有办法按下标访问元组?

4 个答案:

答案 0 :(得分:7)

不,您只能通过直接指定索引来访问元组元素,例如

tuples.5

为了您的目的,您应该只使用一个数组。

答案 1 :(得分:4)

如果你愿意在你的元组周围做一个包装,这实际上是可能的。话虽如此,这太可怕了,不要这样做。在其他答案中提出的建议实际上要好得多,但对于教育目的,这是我的榜样。

struct TupleWrapper {
    let tuple: (String, Int, String, String, String, String, String, Bool)    
    let count: Int
    private let mirrors: [MirrorType]

    subscript (index: Int) -> Any {
        return mirrors[index].value
    }

    init(tuple: (String, Int, String, String, String, String, String, Bool)) {
        self.tuple = tuple

        var mirrors = [MirrorType]()
        let reflected = reflect(tuple)

        for i in 0..<reflected.count {
            mirrors.append(reflected[i].1)
        }

        self.mirrors = mirrors
        self.count = mirrors.count
    }
}

let wrapper = TupleWrapper(tuple: ("1", 2, "3", "4", "5", "6", "7", false))
wrapper[0] // "1"
wrapper[wrapper.count - 1] // false

上面的代码使用Swift的反射API来获取元组对象的逻辑子节点,并将它们的镜像添加到一个数组中,我们可以为每个镜像的值下标。这是相当直接的,但是正如你所期望的那样,因为我们在这里使用元组,所以不能以任何方式使它变得动态。包装器必须是针对特定元组类型的。

有关相关阅读,请参阅NSHipster最近的MirrorType文章。

答案 2 :(得分:2)

有可能使用反射:

Mirror(reflecting: tuples).children[AnyIndex(row)].value

答案 3 :(得分:1)

你想要的是元组是不可能的,如果你不想在以后再投射 - 你唯一的选择是结构或类。 struct似乎是一个更好的选择:)

struct MyStruct {
    let opt1 = 0
    let opt2 = 0
    let opt3 = 0
    ...
    let boolThing = false
}