为了庆祝一年的结束和Swift诞生6个月,就2014年度最受喜爱的Swift贴士和技巧,我们访谈了十位钟爱Swift的朋友。感谢他们的分享。
在架构iOS应用程序时,Swift允许更加泛函(functional)的编程方式,所以我一直在学习很多关于泛函编程的知识,从而更好地构思我的Swift代码。以下是目前为止我最喜欢的swift泛函资源:
泛函函数 ——稍微修改函数,可以让代码更具独立性和可测试性。
类型封装——我喜欢用类型别名让代码便于阅读和安全。
类型设计——更多关于用正确的类型设计程序!“为故障设计合理的类型有助于编译器调试程序”
Swift中柯里化函数的实际应用 ——在Haskell中,一个函数只能有一个参数!而Swift没有这个限制,它的确允许“柯里化”或局部应用一个函数,从而有更多可重复使用代码片段。
Swift中的错误处理: 魔法门 ——我喜欢这种错误处理方式的简单性、可读性和安全性,特别是比起我们通常在Objective-C中的处理方式。
Railway oriented programming (video here) – This is in F#, but it’s a great way to think about error handling in code – just design for the happy path!
面向开关的编程 (视频链接)——这是F#语言中的编程方法,但确实是考虑代码错误处理的好办法——只要设计需要的路径!
《Swift泛函编程》——就Swift泛函话题,这是一本比较高阶的书籍,但每次重读我都发现自己会有新的收获。非常适合那些想要深入研究和挖掘泛函世界并应用这些概念到iOS代码中的人。
观看Natasha的视频:Building TableViews in Swift & iOS8
泛函快速排序——下面的快速排序变体在速度上肯定不会赢得任何优势。大部分快速排序的实际实现会占用固定大小的内存。然而,这个片段是编写快速排序最短、最清晰的方式之一:
1 2 3 4 5 6 7 8 9 |
func qsort(input: [Int]) -> [Int] { if let (pivot, rest) = input.decompose { let lesser = rest.filter { $0 < pivot } let greater = rest.filter { $0 >= pivot } return qsort(lesser) + [pivot] + qsort(greater) } else { return [] } } |
它建立在分解片段上:如果数组非空,它使用第一个元素作为基准,将数组分成两个新的数组:第一个只包含较小的元素,第二个只包含较大(或者相等)的元素。然后,它对较小的元素组进行排序,后面追加基准元素,最后追加排序好的较大元素组。
最初出现在http://www.objc.io/snippets/3.html页面上
观看Chris的视频:Functional Programming in Swift
我喜欢的一个很棒(也许并不实用)的Swift技巧是可以设置一个委托到一个匿名类的实例,通过创建一个定义了指定类的闭包,让闭包能够返回这个类的一个新实例,并运行此闭包。听起来挺复杂,所以我这里有一些示例代码。
你可以观看Austin的视频:Swift: Enums, Pattern Matching & Generics & Lessons Learned Building “2048” in Swift,或者查看他的博客。
这是我在xcode中处理所有问题必不可少的bash别名(特别是sourcekit问题):
1 |
alias sourcekitsad='rm -rf ~/Library/Developer/Xcode/DerivedData' |
你可以观看Clay的12 Apps of Swiftmas视频,或者在GitHub查看他。
最喜欢的细节可能是String不符合可打印性,所以技术上没有保证String可以进行string插值。我想它能工作只能是因为String可以桥接到NSString,于是拥有了-description方法。
你可以查看Michael的12 Apps of Swiftmas演示文档,或者查看他的博客。
Swift看上去是一门足够优雅的语言,我并不特别觉得自己需要用特殊技巧玩hack。我的确喜欢和原始类型一起使用枚举,像这样:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
public enum ReminderTimeType: String { case Evening = "this evening" case Tomorrow = "tomorrow" case Weekend = "this weekend" case NextWeek = "next week" case CoupleWeeks = "in a couple weeks" case CoupleMonths = "in a couple months" case Someday = "someday" public static let array = [ Evening, Tomorrow, Weekend, NextWeek, CoupleWeeks, CoupleMonths, Someday ] public static let rawArray = array.map { $0.rawValue } } |
你可以观看David的视频:Converting Objective-C to Swift,或者在GitHub上查看他。
Alexis Gallagher
资深iOS开发者
我最喜欢的Swift细节,技巧,资源或其他方面?我现在最喜欢的两个技巧是:REPL(Read-Eval-Print Loop,读取-求值-输出)和随手写函数
1 |
func typeof<T>(@autoclosure () -> T) -> Any.Type { return T.self } |
可以用来获取表达式的静态类型而不必执行该表达式。未备注的私有函数_stdlib_getDemangledTypeName可以用来获取任意实例值的类型名。
你可以阅读Alexs的12 Apps of Swiftmas演示文档,或者关注他的Twitter @alexisgallagher。
JP Simard
Realm iOS工程师
像下面这样使用nm工具挖掘libswiftCore.dylib,你可以获得所有Swift私有标准库函数:
1 2 |
cd `xcode-select -p`/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx nm -a libswiftCore.dylib | grep "T _swift_stdlib_" |
一些非常有用的函数会暴露给用户,像_stdlib_getTypeName(), _stdlib_demangleName()和 _stdlib_conformsToProtocol() 之间的一些其他函数。
你可以观看JP的视频:Swift for JavaScript Developers & Swift for Rubyists.
这是一种hack,但事实证明,当结构中所有成员类型相同时(例如都是浮点型),Swift允许你将一个均匀阵列视为一个指向结构成员类型的指针。利用这一点可以简洁地创建顶点数据的Metal缓冲区,而不需要一堆难看的转换。