浅谈Swift新特性

这篇文章写于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有自动补全但是我觉得还是不能忍。。。