- <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声明常量。
- varmyVariable=42
- myVariable=50
- letmyConstant=42
类型推导
- letexplicitDouble:Double=70
- letlabel="Thewidthis"
- letwidth=94
- letwidth=label+String(width)
字符串格式化
Swift使用\(item)的形式进行字符串格式化:
- letapples=3
- letoranges=5
- letappleSummary="Ihave\(apples)apples."
- letappleSummary="Ihave\(apples+oranges)piecesoffruit."
数组和字典
Swift使用[]操作符声明数组(array)和字典(dictionary):
- varshoppingList=["catfish","water","tulips","bluepaint"]
- shoppingList[1]="bottleofwater"
- varoccupations=[
- "Malcolm":"Captain",
- "Kaylee":"Mechanic",
- ]
- occupations["Jayne"]="PublicRelations"
一般使用初始化器(initializer)语法创建空数组和空字典:
- letemptyArray=String[]()
- letemptyDictionary=Dictionary<String,Float>()
如果类型信息已知,则可以使用[]声明空数组,使用[:]声明空字典。
控制流
概览
Swift的条件语句包含if和switch,循环语句包含for-in、for、while和do-while,循环/判断条件不需要括号,但循环/判断体(body)必需括号:
可空类型
结合if和let,可以方便的处理可空变量(nullable variable)。对于空值,需要在类型声明后添加?显式标明该类型可空。
- varoptionalString:String?="Hello"
- optionalString==nil
- varoptionalName:String?="JohnAppleseed"
- vargretting="Hello!"
- ifletname=optionalName{
- gretting="Hello,\(name)"
- }
灵活的switch
Swift中的switch支持各种各样的比较操作:
- letvegetable="redpepper"
- switchvegetable{
- case"celery":
- letvegetableComment="Addsomeraisinsandmakeantsonalog."
- case"cucumber","watercress":
- letvegetableComment="Thatwouldmakeagoodteasandwich."
- caseletxwherex.hasSuffix("pepper"):
- letvegetableComment="Isitaspicy\(x)?"
- default:
- letvegetableComment="Everythingtastesgoodinsoup."
- }
其它循环
for-in除了遍历数组也可以用来遍历字典:
- letinterestingNumbers=[
- "Prime":[2,3,5,7,11,13],
- "Fibonacci":[1,1,2,8],
- "Square":[1,4,9,16,25],
- ]
- varlargest=0
- for(kind,numbers)ininterestingNumbers{
- fornumberinnumbers{
- ifnumber>largest{
- largest=number
- }
- }
- }
- largest
while循环和do-while循环:
- varn=2
- whilen<100{
- n=n*2
- }
- n
- varm=2
- do{
- m=m*2
- }whilem<100
- m
Swift支持传统的for循环,此外也可以通过结合..(生成一个区间)和for-in实现同样的逻辑。
- varfirstForLoop=0
- foriin0..3{
- firstForLoop+=i
- }
- firstForLoop
- varsecondForLoop=0
- forvari=0;i<3;++i{
- secondForLoop+=1
- }
- secondForLoop
注意:Swift除了..还有…:..生成前闭后开的区间,而…生成前闭后闭的区间。
函数和闭包
Swift使用func关键字声明函数:
- funcgreet(name:String,day:String)->String{
- return"Hello\(name),todayis\(day)."
- }
- greet("Bob","Tuesday")
通过元组(Tuple)返回多个值:
- funcgetGasPrices()->(Double,Double,Double){
- return(3.59,3.69,3.79)
- }
- getGasPrices()
- funcsumOf(numbers:Int...)->Int{
- varsum=0
- fornumberinnumbers{
- sum+=number
- }
- returnsum
- }
- sumOf()
- sumOf(42,597,12)
函数也可以嵌套函数:
- funcmakeIncrementer()->(Int->Int){
- funcaddOne(number:Int)->Int{
- return1+number
- }
- returnaddOne
- }
- varincrement=makeIncrementer()
- increment(7)
- funchasAnyMatches(list:Int[],condition:Int->Bool)->Bool{
- foriteminlist{
- ifcondition(item){
- returntrue
- }
- }
- returnfalse
- }
- funclessThanTen(number:Int)->Bool{
- returnnumber<10
- }
- varnumbers=[20,19,12]
- hasAnyMatches(numbers,lessThanTen)
闭包
本质来说,函数是特殊的闭包,Swift中可以利用{}声明匿名闭包:
- numbers.map({
- (number:Int)->Intin
- letresult=33*number
- returnresult
- })
当闭包的类型已知时,可以使用下面的简化写法:
- sort([1,12,2]){$0>$1}
类和对象
创建和使用类
Swift使用class创建一个类,类可以包含字段和方法:
- classShape{
- varnumberOfSides=0
- funcsimpleDescription()->String{
- return"Ashapewith\(numberOfSides)sides."
- }
- }
创建Shape类的实例,并调用其字段和方法。
- varshape=Shape()
- shape.numberOfSides=7
- varshapeDescription=shape.simpleDescription()
通过init构建对象,既可以使用self显式引用成员字段(name),也可以隐式引用(numberOfSides)。
- classNamedShape{
- varnumberOfSides:Int=0
- varname:String
- init(name:String){
- self.name=name
- }
- funcsimpleDescription()->String{
- return"Ashapewith\(numberOfSides)sides."
- }
- }
使用deinit进行清理工作。
继承和多态
- classSquare:NamedShape{
- varsideLength:Double
- init(sideLength:Double,name:String){
- self.sideLength=sideLength
- super.init(name:name)
- numberOfSides=4
- }
- funcarea()->Double{
- returnsideLength*sideLength
- }
- overridefuncsimpleDescription()->String{
- return"Asquarewithsidesoflength\(sideLength)."
- }
- }
- lettest=Square(sideLength:5.2,name:"mytestsquare")
- test.area()
- test.simpleDescription()
注意:如果这里的simpleDescription方法没有被标识为override,则会引发编译错误。
- classEquilateralTriangle:NamedShape{
- varsideLength:Double=0.0
- init(sideLength:Double,name:String){
- self.sideLength=sideLength
- super.init(name:name)
- numberOfSides=3
- }
- varperimeter:Double{
- get{
- return3.0*sideLength
- }
- set{
- sideLength=newValue/3.0
- }
- }
- overridefuncsimpleDescription()->String{
- return"Anequilateraltriaglewithsidesoflength\(sideLength)."
- }
- }
- vartriangle=EquilateralTriangle(sideLength:3.1,name:"atriangle")
- triangle.perimeter
- triangle.perimeter=9.9
- triangle.sideLength
注意:赋值器(setter)中,接收的值被自动命名为newValue。
willSet和didSet
EquilateralTriangle的构造器进行了如下操作:
1.为子类型的属性赋值。
如果不需要计算属性的值,但需要在赋值前后进行一些操作的话,使用willSet和didSet:
- classTriangleAndSquare{
- vartriangle:EquilateralTriangle{
- willSet{
- square.sideLength=newValue.sideLength
- }
- }
- varsquare:Square{
- willSet{
- triangle.sideLength=newValue.sideLength
- }
- }
- init(size:Double,name:String){
- square=Square(sideLength:size,name:name)
- triangle=EquilateralTriangle(sideLength:size,name:name)
- }
- }
- vartriangleAndSquare=TriangleAndSquare(size:10,name:"anothertestshape")
- triangleAndSquare.square.sideLength
- triangleAndSquare.square=Square(sideLength:50,name:"largersquare")
- triangleAndSquare.triangle.sideLength
从而保证triangle和square拥有相等的sideLength。
- classCounter{
- varcount:Int=0
- funcincrementBy(amount:Int,numberOfTimestimes:Int){
- count+=amount*times
- }
- }
- varcounter=Counter()
- counter.incrementBy(2,numberOfTimes:7)
注意Swift支持为方法参数取别名:在上面的代码里,numberOfTimes面向外部,times面向内部。
?的另一种用途
- letoptionalSquare:Square?=Square(sideLength:2.5,name:"optional
- square")
- letsideLength=optionalSquare?.sideLength
枚举和结构
枚举
使用enum创建枚举——注意Swift的枚举可以关联方法:
- enumRank:Int{
- caseAce=1
- caseTwo,Three,Four,Five,Six,Seven,Eight,Nine,Ten
- caseJack,Queen,King
- funcsimpleDescription()->String{
- switchself{
- case.Ace:
- return"ace"
- case.Jack:
- return"jack"
- case.Queen:
- return"queen"
- case.King:
- return"king"
- default:
- returnString(self.toRaw())
- }
- }
- }
- letace=Rank.Ace
- letaceRawValue=ace.toRaw()
使用toRaw和fromRaw在原始(raw)数值和枚举值之间进行转换:
- ifletconvertedRank=Rank.fromRaw(3){
- letthreeDescription=convertedRank.simpleDescription()
- }
注意:枚举中的成员值(member value)是实际的值(actual value),和原始值(raw value)没有必然关联。
一些情况下枚举不存在有意义的原始值,这时可以直接忽略原始值:
- enumSuit{
- caseSpades,Hearts,Diamonds,Clubs
- funcsimpleDescription()->String{
- switchself{
- case.Spades:
- return"spades"
- case.Hearts:
- return"hearts"
- case.Diamonds:
- return"diamonds"
- case.Clubs:
- return"clubs"
- }
- }
- }
- lethearts=Suit.Hearts
- letheartsDescription=hearts.simpleDescription()
除了可以关联方法,枚举还支持在其成员上关联值,同一枚举的不同成员可以有不同的关联的值:
- enumServerResponse{
- caseResult(String,String)
- caseError(String)
- }
- letsuccess=ServerResponse.Result("6:00am","8:09pm")
- letfailure=ServerResponse.Error("Outofcheese.")
- switchsuccess{
- caselet.Result(sunrise,sunset):
- letserverResponse="Sunriseisat\(sunrise)andsunsetisat\(sunset)."
- caselet.Error(error):
- letserverResponse="Failure...\(error)"
- }
结构
Swift使用struct关键字创建结构。结构支持构造器和方法这些类的特性。结构和类的最大区别在于:结构的实例按值传递(passed by value),而类的实例按引用传递(passed by reference)。
- structCard{
- varrank:Rank
- varsuit:Suit
- funcsimpleDescription()->String{
- return"The\(rank.simpleDescription())of\(suit.simpleDescription())"
- }
- }
- letthreeOfSpades=Card(rank:.Three,suit:.Spades)
- letthreeOfSpadesDescription=threeOfSpades.simpleDescription()
协议(protocol)和扩展(extension)
协议
Swift使用protocol定义协议:
- protocolExampleProtocol{
- varsimpleDescription:String{get}
- mutatingfuncadjust()
- }
类型、枚举和结构都可以实现(adopt)协议:
- classSimpleClass:ExampleProtocol{
- varsimpleDescription:String="Averysimpleclass."
- varanotherProperty:Int=69105
- funcadjust(){
- simpleDescription+="Now100%adjusted."
- }
- }
- vara=SimpleClass()
- a.adjust()
- letaDescription=a.simpleDescription
- structSimpleStructure:ExampleProtocol{
- varsimpleDescription:String="Asimplestructure"
- mutatingfuncadjust(){
- simpleDescription+="(adjusted)"
- }
- }
- varb=SimpleStructure()
- b.adjust()
- letbDescription=b.simpleDescription
扩展
- extensionInt:ExampleProtocol{
- varsimpleDescription:String{
- return"Thenumber\(self)"
- }
- mutatingfuncadjust(){
- self+=42
- }
- }
- 7.simpleDescription
泛型(generics)
Swift使用<>来声明泛型函数或泛型类型:
- funcrepeat(item:ItemType,times:Int)->ItemType[]{
- varresult=ItemType[]()
- foriin0..times{
- result+=item
- }
- returnresult
- }
- repeat("knock",4)
Swift也支持在类、枚举和结构中使用泛型:
- //ReimplementtheSwiftstandardlibrary'soptionaltype
- enumOptionalValue{
- caseNone
- caseSome(T)
- }
- varpossibleInteger:OptionalValue=.None
- possibleInteger=.Some(100)
有时需要对泛型做一些需求(requirements),比如需求某个泛型类型实现某个接口或继承自某个特定类型、两个泛型类型属于同一个类型等等,Swift通过where描述这些需求:
- funcanyCommonElements<T,UwhereT:Sequence,U:Sequence,T.GeneratorType.Element:Equatable,T.GeneratorType.Element==U.GeneratorType.Element>(lhs:T,rhs:U)->Bool{
- forlhsIteminlhs{
- forrhsIteminrhs{
- iflhsItem==rhsItem{
- returntrue
- }
- }
- }
- returnfalse
- }
- anyCommonElements([1,3],[3])
本文转自 Lucida的博客 感谢原作者