- <prename="code"class="objc">转自:http://letsswift.com/2014/06/swift_overview/
Swift语言概览
基本概念
注:这一节的代码源自
The Swift Programming Language中的A Swift Tour。
Hello,world
类似于脚本语言,下面的代码即是一个完整的Swift程序。
- println("Hello,world")
Swift使用var声明变量,let声明常量。
- letexplicitDouble:Double=70
Swift使用\(item)的形式进行字符串格式化:
数组和字典
Swift使用[]操作符声明数组(array)和字典(dictionary):
一般使用初始化器(initializer)语法创建空数组和空字典:
- letemptyArray=String[]() @H_403_143@letemptyDictionary=Dictionary<String,Float>()
如果类型信息已知,则可以使用[]声明空数组,使用[:]声明空字典。
控制流
概览
Swift的条件语句包含if和switch,循环语句包含for-in、for、while和do-while,循环/判断条件不需要括号,但循环/判断体(body)必需括号:
可空类型
结合if和let,可以方便的处理可空变量(nullable variable)。对于空值,需要在类型声明后添加?显式标明该类型可空。
灵活的switch
Swift中的switch支持各种各样的比较操作:
- letvegetable="redpepper" @H_403_143@switchvegetable{
- case"celery": @H_403_143@letvegetableComment="Addsomeraisinsandmakeantsonalog."
- case"cucumber","watercress": @H_403_143@letvegetableComment="Thatwouldmakeagoodteasandwich."
- caseletxwherex.hasSuffix("pepper"): @H_403_143@letvegetableComment="Isitaspicy\(x)?"
- default: @H_403_143@letvegetableComment="Everythingtastesgoodinsoup."
- }
其它循环
for-in除了遍历数组也可以用来遍历字典:
while循环和do-while循环:
函数和闭包
Swift使用func关键字声明函数:
通过元组(Tuple)返回多个值:
闭包
本质来说,函数是特殊的闭包,Swift中可以利用{}声明匿名闭包:
当闭包的类型已知时,可以使用下面的简化写法:
- sort([1,12,2]){$0>$1}
类和对象
创建和使用类
Swift使用class创建一个类,类可以包含字段和方法:
通过init构建对象,既可以使用self显式引用成员字段(name),也可以隐式引用(numberOfSides)。
使用deinit进行清理工作。
继承和多态
- classSquare:NamedShape{ @H_403_143@varsideLength:Double
- @H_403_143@init(sideLength:Double,name:String){
- self.sideLength=sideLength @H_403_143@super.init(name:name)
- numberOfSides=4 @H_403_143@}
- @H_403_143@funcarea()->Double{
- returnsideLength*sideLength @H_403_143@}
- @H_403_143@overridefuncsimpleDescription()->String{
- return"Asquarewithsidesoflength\(sideLength)." @H_403_143@}
- } @H_403_143@lettest=Square(sideLength:5.2,name:"mytestsquare")
- test.area() @H_403_143@test.simpleDescription()
注意:如果这里的simpleDescription方法没有被标识为override,则会引发编译错误。
- classEquilateralTriangle:NamedShape{ @H_403_143@varsideLength:Double=0.0
- @H_403_143@init(sideLength:Double,name:String){
- self.sideLength=sideLength @H_403_143@super.init(name:name)
- numberOfSides=3 @H_403_143@}
- @H_403_143@varperimeter:Double{
- get{ @H_403_143@return3.0*sideLength
- } @H_403_143@set{
- sideLength=newValue/3.0 @H_403_143@}
- } @H_403_143@
- overridefuncsimpleDescription()->String{ @H_403_143@return"Anequilateraltriaglewithsidesoflength\(sideLength)."
- } @H_403_143@}
- vartriangle=EquilateralTriangle(sideLength:3.1,name:"atriangle") @H_403_143@triangle.perimeter
- triangle.perimeter=9.9 @H_403_143@triangle.sideLength
注意:赋值器(setter)中,接收的值被自动命名为newValue。
willSet和didSet
EquilateralTriangle的构造器进行了如下操作:
1.为子类型的属性赋值。
如果不需要计算属性的值,但需要在赋值前后进行一些操作的话,使用willSet和didSet:
- classTriangleAndSquare{ @H_403_143@vartriangle:EquilateralTriangle{
- willSet{ @H_403_143@square.sideLength=newValue.sideLength
- } @H_403_143@}
- varsquare:Square{ @H_403_143@willSet{
- triangle.sideLength=newValue.sideLength @H_403_143@}
- } @H_403_143@init(size:Double,name:String){
- square=Square(sideLength:size,name:name) @H_403_143@triangle=EquilateralTriangle(sideLength:size,name:name)
- } @H_403_143@}
- vartriangleAndSquare=TriangleAndSquare(size:10,name:"anothertestshape") @H_403_143@triangleAndSquare.square.sideLength
- triangleAndSquare.square=Square(sideLength:50,name:"largersquare") @H_403_143@triangleAndSquare.triangle.sideLength
从而保证triangle和square拥有相等的sideLength。
?的另一种用途
- letoptionalSquare:Square?=Square(sideLength:2.5,name:"optional @H_403_143@square")
- letsideLength=optionalSquare?.sideLength
枚举和结构
枚举
使用enum创建枚举——注意Swift的枚举可以关联方法:
- enumRank:Int{ @H_403_143@caseAce=1
- caseTwo,Three,Four,Five,Six,Seven,Eight,Nine,Ten @H_403_143@caseJack,Queen,King
- funcsimpleDescription()->String{ @H_403_143@switchself{
- case.Ace: @H_403_143@return"ace"
- case.Jack: @H_403_143@return"jack"
- case.Queen: @H_403_143@return"queen"
- case.King: @H_403_143@return"king"
- default: @H_403_143@returnString(self.toRaw())
- } @H_403_143@}
- } @H_403_143@letace=Rank.Ace
- letaceRawValue=ace.toRaw()
使用toRaw和fromRaw在原始(raw)数值和枚举值之间进行转换:
- ifletconvertedRank=Rank.fromRaw(3){ @H_403_143@letthreeDescription=convertedRank.simpleDescription()
- }
注意:枚举中的成员值(member value)是实际的值(actual value),和原始值(raw value)没有必然关联。
一些情况下枚举不存在有意义的原始值,这时可以直接忽略原始值:
- enumSuit{ @H_403_143@caseSpades,Hearts,Diamonds,Clubs
- funcsimpleDescription()->String{ @H_403_143@switchself{
- case.Spades: @H_403_143@return"spades"
- case.Hearts: @H_403_143@return"hearts"
- case.Diamonds: @H_403_143@return"diamonds"
- case.Clubs: @H_403_143@return"clubs"
- } @H_403_143@}
- } @H_403_143@lethearts=Suit.Hearts
- letheartsDescription=hearts.simpleDescription()
除了可以关联方法,枚举还支持在其成员上关联值,同一枚举的不同成员可以有不同的关联的值:
- enumServerResponse{ @H_403_143@caseResult(String,String)
- caseError(String) @H_403_143@}
- @H_403_143@letsuccess=ServerResponse.Result("6:00am","8:09pm")
- letfailure=ServerResponse.Error("Outofcheese.") @H_403_143@
- switchsuccess{ @H_403_143@caselet.Result(sunrise,sunset):
- letserverResponse="Sunriseisat\(sunrise)andsunsetisat\(sunset)." @H_403_143@caselet.Error(error):
- letserverResponse="Failure...\(error)" @H_403_143@}
结构
Swift使用struct关键字创建结构。结构支持构造器和方法这些类的特性。结构和类的最大区别在于:结构的实例按值传递(passed by value),而类的实例按引用传递(passed by reference)。
协议(protocol)和扩展(extension)
协议
Swift使用protocol定义协议:
类型、枚举和结构都可以实现(adopt)协议:
- classSimpleClass:ExampleProtocol{ @H_403_143@varsimpleDescription:String="Averysimpleclass."
- varanotherProperty:Int=69105 @H_403_143@funcadjust(){
- simpleDescription+="Now100%adjusted." @H_403_143@}
- } @H_403_143@vara=SimpleClass()
- a.adjust() @H_403_143@letaDescription=a.simpleDescription
- @H_403_143@structSimpleStructure:ExampleProtocol{
- varsimpleDescription:String="Asimplestructure" @H_403_143@mutatingfuncadjust(){
- simpleDescription+="(adjusted)" @H_403_143@}
- } @H_403_143@varb=SimpleStructure()
- b.adjust() @H_403_143@letbDescription=b.simpleDescription
扩展
泛型(generics)
Swift使用<>来声明泛型函数或泛型类型:
有时需要对泛型做一些需求(requirements),比如需求某个泛型类型实现某个接口或继承自某个特定类型、两个泛型类型属于同一个类型等等,Swift通过where描述这些需求:
- funcanyCommonElements<T,UwhereT:Sequence,U:Sequence,T.GeneratorType.Element:Equatable,T.GeneratorType.Element==U.GeneratorType.Element>(lhs:T,rhs:U)->Bool{ @H_403_143@forlhsIteminlhs{
- forrhsIteminrhs{ @H_403_143@iflhsItem==rhsItem{
- returntrue @H_403_143@}
- } @H_403_143@}
- returnfalse @H_403_143@}
- anyCommonElements([1,3],[3])
本文转自 Lucida的博客 感谢原作者