闭包的写法
let array = [23, 45, 12, 89, 98, 55, 7]
array.sort({ (one: Int, two: Int) -> Bool in
return one < two
})
array.sort({ (one, two) in one < two })
array.sort({ one, two in one < two })
array.sort({ $0 < $1 })
array.sort { $0 < $1 }
array.sort(<)
下面的代码输出是什么?并说明理由。
var thing = "cars"
let closure = { [thing] in
print("I love \\(thing)")
}
thing = "airplanes"
closure()
答案:输出的是:I love cars。
当闭包被声明的时候,
抓捕列表就复制一份thing变量,
所以被捕捉的值并没有改变,
即使你给thing赋了一个新值。
如果你要忽视闭包中捕捉列表的值,
那么编译器引用那个值而不是复制。
这种情况下,被引用变量的值的变化将会反映到闭包中,正如下面的代码所示:
var thing = "cars"
let closure = {
print("I love \\(thing)")
}
thing = "airplanes"
closure() // Prints "I love airplanes"
下面是一个全局函数,这个函数的功能是计算数组中特殊值得个数。(待校验)
1
2
3
4
5
6
func countUniques(array: Array) -> Int {
let sorted = array.sort(<)
let initial: (T?, Int) = (.None, 0)
let reduced = sorted.reduce(initial) { ($1, $0.0 == $1 ? $0.1 : $0.1 + 1) }
return reduced.1
}
它使用了< 和==运算符,他们限制着T(占位类型)的实际类型,也就是说T必须遵循Comparable协议。你可以这样使用它:
1
countUniques([1, 2, 3, 3]) // result is 3
现在要求你重写上面的方法作为Array的扩展方法,然后你就可以这样写代码:
1
[1, 2, 3, 3].countUniques() // should print 3
如何实现?
答案:在Swift 2.0 中,泛类型可以使用类型约束条件被强制扩展。但是假如这个泛类型不满足这个类型的约束条件,那么这个扩展方法既不可见也无法调用。
所以countUniques全局函数可以作为Array的扩展方法被重写如下:
extension Array where Element: Comparable {
func countUniques() -> Int {
let sorted = sort(<)
let initial: (Element?, Int) = (.None, 0)
let reduced = sorted.reduce(initial) { ($1, $0.0 == $1 ? $0.1 : $0.1 + 1) }
return reduced.1
}
}
注意:只有元类型实现了Comparable协议新的方法才可以被使用。例如,如果你在全部是UIView对象的数组中调用countUniques,编译器将会报错。
import UIKit
let a = [UIView(), UIView()]
a.countUniques() // compiler error here because UIView doesn't implement Comparable