这篇文章写于2015年6月9日,学习Swift时所写。从原来的站点移动而来。
期末考试全部结束了,终于有时间写写自己的心得和总结了。在考期间隙的两个星期,简单看了一下Swift,在此写写Swift相较于Java的一些新的特性。
运行环境:OS X 10.10.3 | Xcode 6.3.2 | Swift 1.2
一、表达方式
Swift中的一些表达方式,与C风格的表达方式有些不同。
常量赋值
const int x = 1; // Java let x: Int = 1 // Swift
变量赋值
int y = 2; // Java var y: Int = 2 // Swift
函数表示
int func(char arg0, String arg1){} //Java func(arg0: Character, arg1: String) -> Int {} // Swift
switch不需要写break
switch (x) { case 1: x++ case 2: x-- default: x = 0 }
每一行不需要分号结尾,除非需要一行表达多个语句。
二、强类型检查
Swift是强类型语言,在语言中没有指针的概念,取而代之的是引用,这点跟Java类似。
值的缺失
var s1: String = "123" //此处的s1必须有值 var s2: String? = nil //此处的s2可以有值,也可以为nil。Swift中用nil代表值缺失。
缺失类型与非缺失类型的转换
var s2: String? = "abc" //s2允许值缺失 var s1: String = s2 as! String //用as!声明s2强制变成非缺失类型。如果此时s2为nil,程序会崩溃。
还有其它的一些编程上的限制,例如子类方法覆盖父类方法必须加@override。
三、计算型属性
计算型属性可以定义在类、结构体和枚举中。这种属性不直接储存值,而是提供一个 getter 来获取值,一个可选的 setter 来间接设置其他属性或变量的值。
struct square { var a = 0 var s: Int { // s为计算属性 get { return a * a } } }
四、扩展类
扩展可以向已有类型添加计算型属性。通过这种方法可以给String类型添加length属性(为什么Swift语言不自带length属性。。。)
extension Double { var km: Double { return self * 1_000.0 } var m : Double { return self } var cm: Double { return self / 100.0 } var mm: Double { return self / 1_000.0 } var ft: Double { return self / 3.28084 } }
五、元组
元组是多个值组合而成的复合值。元组中的值可以是任意类型,而且每一个元素的类型可以是不同的。不用在函数返回值需要多个的情况纠结了!
let http404Error = (404, "Not Found") // 元组的赋值 let (statusCode, statusMessage) = http404Error // 元组的拆解 let (statusCode, _) = http404Error // 只拆解出部分 func(arg0: Int, arg1: String) -> (Int, String){} // 函数可以返回元组
六、闭包
其实这玩意很像匿名函数。
var reversed = sort(names, { (s1: String, s2: String) -> Bool in return s1 > s2 })
然而在这种情况下,可以根据上下文推断类型,所以可以这么写:
var reversed = sort(names, { s1, s2 in return s1 > s2 } )
有些神奇的是,对于这种单表达式的闭包,甚至可以偷懒连return都不用敲。。。
reversed = sort(names, { s1, s2 in s1 > s2 } )
但还没有结束,Swift提供了参数名称缩写功能,所以。。。
reversed = sort(names, { $0 > $1 } )
Swift的String类型定义了关于大于号 (>) 的字符串实现,而这正好与sort函数的第二个参数需要的函数类型相符合。
reversed = sort(names, >)
真是神奇的偷懒技巧。。。
七、一点感想
虽然Swift看起来很实用的样子,但是由于语言还不够成熟,有时候用起来也是很令人心烦的。
就拿Cocoa框架中的NSString来说,通过()转成String的时候,字符会被Optional()包围。每次转换都要截取一下。
有时候想通过下标获取String中的单个字符。[]中竟然要填一个String.Index类型的东西。而这个东西却要用advance函数来得到。advance函数的时间复杂度可是O(n)的。估计问题的根源在于Swift的String支持Unicode。
还有,Java里的s.split()在Swift中是s.componentsSeparatedByString(),Java里的s.replace()在Swift中是s.stringByReplacingOccurrencesOfString()。虽然Xcode有自动补全但是我觉得还是不能忍。。。