Swift:使用变量/参数访问元组元素?

Swift:使用变量/参数访问元组元素?,swift,Swift,以下是情况的[一般版本]: let tuple: (first: Int, second: Int, third: Int) // tuple.0 is equivalent to tuple.first enum TupleIndex: Int { case first = 0, second, third } func selectTupleElement (index: TupleIndex) { let indexNum = index.rawValue

以下是情况的[一般版本]:

let tuple: (first: Int, second: Int, third: Int) // tuple.0 is equivalent to  tuple.first

enum TupleIndex: Int { 
    case first = 0, second, third 
}

func selectTupleElement (index: TupleIndex) {
    let indexNum = index.rawValue
    let tupleElement = tuple.indexNum // Oh noooooo!!!
}
编译器将上面最后一行中指出的问题点读取为“tuple的
indexNum
属性或元素”(当然不存在),而不是“tuple的元素在索引处等于
indexNum
的值”

有没有一种方法可以使用元组来完成我想做的事情?

您可以利用运行时自省来有条件地提取固定大小和相同类型成员的元组的
n
:th成员(例如,下面:为具有统一类型成员的arity 3元组实现)并(有条件地)将其转换为成员的类型。例如:

func selectTupleElementFor<T>(memberNumber: Int, inTuple tuple: (T, T, T)) -> T? {
    return Mirror(reflecting: tuple).children.enumerated()
        .first(where: { $0.0 == memberNumber - 1 }).flatMap { $1.1 as? T }
}

// example usage
let tuple: (first: Int, second: Int, third: Int) = (10, 20, 30)
if let tupleMember = selectTupleElementFor(memberNumber: 2, inTuple: tuple) {
    print(tupleMember) // 20
}

我想到了一种方法:
让arrayInstead=[Int]()
为什么不使用数组?使用元组有什么好处?@Sweeper,我想使用元组,这样我就可以命名元素,并通过这些名称索引引用元素,而不是数组中需要的数字索引。然而,我已经找到了一个解决方案,那就是创建等于索引数的变量,然后我可以说
让第一个=1

让第一个=1

让选择=数组[indexNum]




但是我很好奇它是否可以用元组来完成。只是好奇!。。。然后我意识到建议的dupe目标包含一个具有类似内省方法的解决方案,由我自己编写,doh xD无论如何都会保留上面的答案,因为它显示了一个使用OPs own
TupleIndex
类型的示例,并且使用的内省实现与(不可接受)中的略有不同dupe目标的答案。请注意,我认为为
子对象
本身(例如在您的另一个答案中)推进索引比在本例中使用
首先(其中:)
枚举()
更好,因为前者可以利用O(1)索引来对随机访问集合进行索引,而后者则不能(虽然我不经常使用
Mirror
,所以不知道在什么情况下它会返回一个
children
集合,该集合是或不是随机访问的-也许你知道?:)@Hamish the
children
调用返回一个类型擦除的集合包装,我认为它不是随机访问(即使基础类型擦除的集合是);与类型擦除的集合包装器相比,也就是说。无论如何,由于我们正在对元组进行内省(使用静态指定固定算术的函数),我不认为随机访问vs
O(n)
遍历应该是一个问题……除非“元组索引访问”它本身是某些HPC应用程序的一部分。但在这样的应用程序中(或在上面的应用程序中,对于这一部分:只是一种技术方法,但任何本机随机访问集合都是可取的:或者只是一个自定义
结构
类型的数组)使用runtime introsp是不合理的抛开随机访问不谈,我同意另一种解决方案与此方案相比也有其他好处:通常更容易(/更好)的语义,即使我个人喜欢(并跳到!)每次使用
可选
的整洁
映射
平面映射
方法,谢谢您的反馈!元组长度是固定的,所以这两种方法在技术上都是O(1)——这绝对不是我想说的那么大的问题(我刚刚看到了使用
首先(其中:)
进行索引,并稍微抽动了一下:P)。尽管请注意,如果基础集合是,则
AnyCollection
仍然可以是随机访问–它只是在一天结束时将对索引方法的调用转发给基础集合:)
enum TupleIndex: Int { 
    case first = 0, second, third 
}

func selectTupleElementFor<T>(tupleIndex: TupleIndex, inTuple tuple: (T, T, T)) -> T? {
    return Mirror(reflecting: tuple).children.enumerated()
        .first(where: { $0.0 == tupleIndex.rawValue }).flatMap { $1.1 as? T }
}

// example usage
let tuple: (first: Int, second: Int, third: Int) = (10, 20, 30)
if let tupleMember = selectTupleElementFor(tupleIndex: .second, inTuple: tuple) {
    print(tupleMember) // 20
}