Swift 惯用语法
久而久之,Swift 发展出一种别具一格的专用语法——即一组与其他语言相差甚远的基本惯用语法 (core idioms)。许多来自 Objective-C、Ruby、Java、Python 等等语言的开发者纷纷投向 Swift 的麾下。数日前,Nicholas T Chambers 让我帮他来磨练这门新习得的语言。他通过将 Ruby 代码移植为 Swift 的方式,来构建自己基本的编程技能。他所移植的代码是这样的: ruby def find_common(collection) sorted = {} most = [0,0] for item in collection do if not sorted.key? item then sorted[item] = 0 end sorted[item] += 1 if most[1] < sorted[item] then most[0] = item most[1] = sorted[item] end end return most end 然后他所尝试改编而成的 Swift 代码为: func find_common(items: [Int]) -> [Int] { var sorted = [Int: Int]() var most = [0,0] for item in items { if sorted[item] == nil { sorted[item] = 0 } sorted[item]! += 1 if most[1] < sorted[item]! { most[0] = item most[1] = sorted[item]! } } return most } 除了一些强制解包的代码外,这两者之间几乎没有任何区别。我对 Ruby 并不是了如指掌,但是这两段代码感觉仍然还是 C 语言的风格,并且也一点都不函数化(是函数式编程领域的意思,而不是「无法工作」的意思)。 我知道 Ruby 支持类似 下面就是经我建议之后重写的版本: import Foundation extension Array where Element: Hashable { /// Returns most popular member of the array /// /// - SeeAlso: https://en.wikipedia.org/wiki/Mode_(statistics) /// func mode() -> (item: Element?,count: Int) { let countedSet = NSCountedSet(array: self) let counts = countedSet.objectEnumerator() .map({ (item: $0 as? Element,count: countedSet.count(for: $0)) }) return counts.reduce((item: nil,count: 0),{ return ($0.count > $1.count) ? $0 : $1 }) } } 就某些方面而言,这种重构显然是作弊了,因为我「借用」了 下面是我关于重构的一些建议和想法:
世间有很多事情既需要顾全大局,也需要深入细节 (A lot of this falls into the big picture little picture dichotomy)。在学习 Swift 的时候,您可能希望从细节开始学习:学习可空值的原理、学习如何正确的使用可空值、学习如何使用函数式编程等等,从而一直学习到如何创建测试、如何编写文档、如何利用协议和泛型。要学的东西实在是纷繁复杂,很难一步登天。 在这些知识的基础之上,又还有基本的 API 用法,这使得学习 Swift 变得更加困难。对于那些刚刚接触苹果开发的人而言,即便他们具备了现代编程语言的基础知识,但是要区分出 Swift 原生类型和 Cocoa 类型的区别并且掌握 Cocoa/Cocoa Touch API 都将是一个重大的挑战。 正因如此,用「更 Swift 化」的方式来编写代码,不仅意味着要使用约定的惯用语法,同时还意味着要记住和使用语言所处平台的相关特性。我希望计数集(以及其他 Cocoa Foundation 当中没被 Swift 原生化的类型)能够成为 Swift 的原生部分。
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |