总结:易错点解析

闭包的写法
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

你可能感兴趣的:(总结:易错点解析)