Swift是Apple最新推出的语言,用于编写iOS和OS X程序,与C语言和Objective-C兼容。本系列的文章中的一些例子,都来自于苹果官方的GUIDE: The Swift Programming Language,有兴趣的同学可以去苹果的官网下载英文原版的iBook。
Swift中不需要main函数,也不需要用;分开每一行的语句,一个简单的Hello world如下所示:
println("Hello, world")
使用let来创建一个常量,使用var来创建一个变量,如下所示:
var myVariable = 42 myVariable = 50 let myConstant = 42
let implicitInt = 72 let implicitDouble = 72.0 let explicitDouble : Double = 72
但是,变量在初始化之外,永远都不会隐式转换类型的。例如有变量:
let label = "number is " let num = 5
let numLabel = label + num
let numLabel = label + String(num)
let numLabel = "number is \(num)"
var shoppingList = ["catfish", "water"] shoppingList[1] = "bottle of water" var occupations = [ "Malcolm": "Captain", "Kaylee": "Mechanic", ] occupations["Jayne"] = "Public Relations"
let emptyArray = [String]() let emptyDictionary = Dictionary<String, Float>()
if、switch中的条件不需要括号,且switch语句中的case不需要加break,因为case中的语句不会跳转到下一个case中。例如:
let hello = "hello" switch hello { case "hello": let lang = "English" case "你好": let lang = "Chinese" default: let lang = "other" } let score = 62 if score >= 60 { let result = "Passed" } else { let result = "No pass" }
循环语句中的条件同样无需添加括号。当在for-in语句中使用一对值时,可以对辞典的键、值进行迭代,例如下面是一个返回辞典中最大值的代码:
let interestingNumbers = [ "Prime": [2, 3, 5, 7, 11, 13], "Fibonacci": [1, 1, 2, 3, 5, 8], "Square": [1, 4, 9, 16, 25], ] var largest = 0 for (kind, numbers) in interestingNumbers{ for number in numbers{ if number > largest { largest = number } } } largest
for i in 0..<4{ } for var i=0; i < 4; ++i { }
使用func定义一个函数,用 -> 表示函数的返回类型,类似于C++11中的函数返回类型后置。函数形参与类型直接用冒号隔开,形参与形参之间用逗号隔开。
func greet(name: String, day: String) -> String { return "Hello \(name), today is \(day)." } greet ("Froser", "Sunday")
func getNumber() -> (Double, Double) { return (1.0, 2.0) }
可以使用...来接收不定长参数,这些不定长参数将作为一个列表:
func sumOf(numbers: Int...) -> Int { var sum = 0; for number in numbers { sum += number } } sumOf() sumOf(1,3,100)
func test() -> Int { var x = 10 func add(){ x += 5 } add() return x }
func makeIncrement() -> (Int -> Int) { func increase(number: Int) -> Int { return number + 1 } return increase }
同理,函数的形参也可以为函数:
func equals (numberA: Int, numberB: Int, equals: (Int, Int) -> Bool ) -> Bool { return equals(numberA, numberB) }
object.save({ (number: Int) -> Int in let result = 3 * number return result })
使用class关键字来创建一个类,类内部可以添加变量、常量和方法(Method)
class Shape{ var numberOfSides = 0 func description() -> String { return "A shape with \(numbeOfSides) sides." } }
如同一般的面向对象编程,用“.”访问对象中的成员。
var shape = Shape() shape.numberOfSides = 7
使用init方法来为类创建一个构造器,用deinit为类创建一个析构器。
就像C++、C#那样,通过在类名称后面加冒号可以表示类的继承。如果子类要覆盖一个基类方法,必须要加上关键字override。意外地覆盖了基类方法却没有加override会导致编译器报错。
class A{ func test(){} } class B : A{ override func test(){} }
class A{ var _property : String = "" var property : String{ get{ return "hello " + _property } set{ _property = newValue } } }
除此之外,Swift还定义了两种属性方法:willSet和didSet,分别代表属性赋值前和赋值后执行的方法。
Swift中,类中的func被称为“方法(Method)”,方法可以访问类成员中的值:
class Counter { var count: Int = 0 func add() { count++ } }
使用enum关键字创建一个枚举类型,并用case定义它的枚举值。枚举类型可以看成是一个类,因为它可以包含自己的方法,当调用自身方法时,一个使用self获取自身的信息:
enum Rank: Int { case Ace = 1 case Two, Three, Four func description() -> String { switch self { case .Ace: return "ace" default: return String(self.toRaw()) } } }
当编译器能够推断出枚举对象的类型时,不必在赋值时加上枚举类型名,如可以将Rank.Ace简化为.Ace。
枚举成员甚至可以带参数:
enum ServerResponse{ case Success(String) case Error(String) } let error = ServerResponse.Error("Password incorrect!")
使用关键字struct创建一个结构,与“类”不同的是,结构在传递时,是按照值传递的,而拷贝则是按照“引用”来传递的。请参考C#、Java中的值传递、引用传递。
协议如同C#、Java中的“接口(Interface)”:
protocol Example{ var description: String { get } mutating func adjust() }
在结构中,实现adjust方法必须在前面添加关键字mutating,表示它会改变自身内部成员的值,而class本身就可以改变自身成员的值,就不必添加了:
class ClassWithDescription : Example { var description: String= "very simple" func adjust(){ description="" } } struct StructWithDescription : Example { var description: String= "very simple" mutating func adjust(){ description="" } }
如同面向对象设计那样,可以用Example类型来定义任何继承了Example协议的对象,但是它只会包含Example协议中的细节。
如同C#中的扩展方法、Objective-C中的类别,使用extension关键字到一个已知类型,我们可以为这种类型添加扩展的属性、方法。
extension Int: Example{ .... } extension Int{ .... }
Swift中有泛型函数、泛型方法、泛型结构、泛型枚举、泛型结构等。泛型的类型写在尖括号<>中:
func repeat<ItemType>(item: ItemType, times: Int) -> [ItemType] { var result = [ItemType]() for i in 0..<times{ result += item } return result } repeat ("knock", 4)
func test<T where T: Sequence> (arg: T){ .... }
以上是列举了一些Swift的语法点,可见Swift吸取了很多语言的成功经验:如Javascript的动态与随意性、C#的属性机制、泛型机制、Java的枚举机制、C++11的后置类型返回,以及简化了for循环的一些写法(这个可能是和Perl学的),让它能成为一门真正的面向对象动态型语言。
之后,我会将Swift语言中的每一个细节都整理出来,希望能和大家一起学习。