我很好奇如何在swift中使用元组进行for循环.
我知道要访问每个成员,您可以使用索引号使用点表示法
var tupleList = ("A",2.9,3,8,5,6,7,8,9)
for each in tupleList {
println(each)
}
Run Code Online (Sandbox Code Playgroud)
//错误:类型不符合协议序列
dan*_*gai 40
是的你可以!
func iterate<C,R>(t:C, block:(String,Any)->R) {
let mirror = reflect(t)
for i in 0..<mirror.count {
block(mirror[i].0, mirror[i].1.value)
}
}
Run Code Online (Sandbox Code Playgroud)
瞧!
let tuple = ((false, true), 42, 42.195, "42.195km")
iterate(tuple) { println("\($0) => \($1)") }
iterate(tuple.0){ println("\($0) => \($1)")}
iterate(tuple.0.0) { println("\($0) => \($1)")} // no-op
Run Code Online (Sandbox Code Playgroud)
请注意,最后一个不是元组,因此没有任何反应(尽管它是1元组或"单个",可以访问内容.0,reflect(it).count是0).
有趣的是,iterate()甚至可以迭代其他类型的集合.
iterate([0,1]) { println("\($0) => \($1)") }
iterate(["zero":0,"one":1]) { println("\($0) => \($1)") }
Run Code Online (Sandbox Code Playgroud)
该系列包括class和struct!
struct Point { var x = 0.0, y = 0.0 }
class Rect { var tl = Point(), br = Point() }
iterate(Point()) { println("\($0) => \($1)") }
iterate(Rect()) { println("\($0) => \($1)") }
Run Code Online (Sandbox Code Playgroud)
警告:作为块的第二个参数传递的值是type Any.您必须将其强制转换为原始类型的值.
dre*_*wag 10
Swift目前不支持迭代元组.
最大的原因是:
tupleList.0.你真的想要一个下标tupleList[0]但是没有提供给我们坦率地说,如果你想迭代它,我看不出你会使用元组而不是数组的原因.
迭代元组是没有意义的,因为:
数组很好地迭代:
var list = ["A",2.9,3,8,5,6,7,8,9]您可以使用反射Swift 4
在操场上尝试一下:
let tuple = (1, 2, "3")
let tupleMirror = Mirror(reflecting: tuple)
let tupleElements = tupleMirror.children.map({ $0.value })
tupleElements
Run Code Online (Sandbox Code Playgroud)
输出:
@dankogai 的优秀解决方案,针对 Swift 3.0 进行了更新:
func iterate<Tuple>(_ tuple:Tuple, body:(_ label:String?,_ value:Any)->Void) {
for child in Mirror(reflecting: tuple).children {
body(child.label, child.value)
}
}
Run Code Online (Sandbox Code Playgroud)
用法与@dankogai 的示例相同(除了 Swift 2 的println()? print()rename)。
请注意,标签现在String?是以前String的类型,以匹配从 Swift 1MirrorType.subscript(…).0到 Swift 3 的类型更改Mirror.Child.label。然而,对于labelless元组labelARG回来为".0",".1",".2"等-这只是nil一些其他类型。
此外,我冒昧地重命名类型和参数以更好地匹配Swift 3 的固化命名标准,并将闭包返回类型更改为Void.
旁注:我注意到有人在这里对我投了反对票——我无法想象为什么,除了(公平的)论点,在 Swift 中围绕反射构建应用程序功能正在侵入类型系统,并且可能会导致整个代码都很糟糕(Swift 的元组应该'不被视为抽象数据类型,而是一小部分变量集合,类似于方法 args)。作为反驳,我最初最终在项目中将其移植到 Swift 3,因为我需要它——为了更好的descriptions 和debugDescriptions。因为健全的调试输出将为您节省数小时的挫折感。;-) 此外,这对于单元测试可能非常有用……因为测试最终最感兴趣的是“此操作的结果是否符合我们的预期?”
| 归档时间: |
|
| 查看次数: |
13870 次 |
| 最近记录: |