加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

Swift概览

发布时间:2020-12-14 06:58:30 所属栏目:百科 来源:网络整理
导读:[javascript] view plain copy print ? prename= "code" class = "objc" 转自:http: //letsswift.com/2014/06/swift_overview/ Swift语言概览 基本概念 注:这一节的代码源自 The Swift Programming Language 中的A Swift Tour。 Hello,world 类似于脚本语
[javascript] view plain copy print ?
  1. <prename="code"class="objc">转自:http://letsswift.com/2014/06/swift_overview/
Swift语言概览
基本概念
注:这一节的代码源自 The Swift Programming Language中的A Swift Tour。
Hello,world
类似于脚本语言,下面的代码即是一个完整的Swift程序。
[objc] view plain copy print ?
  1. println("Hello,world")

变量与常量

Swift使用var声明变量,let声明常量。
[objc] view plain copy print ?
  1. varmyVariable=42
  2. myVariable=50
  3. letmyConstant=42

类型推导
Swift支持类型推导(Type Inference),所以上面的代码不需指定类型,如果需要指定类型:
[objc] view plain copy print ?
  1. letexplicitDouble:Double=70
Swift不支持隐式类型转换(Implicitly casting),所以下面的代码需要显式类型转换(Explicitly casting):
[objc] view plain copy print ?
  1. letlabel="Thewidthis"
  2. letwidth=94
  3. letwidth=label+String(width)

字符串格式化
Swift使用(item)的形式进行字符串格式化:
[objc] view plain copy print ?
  1. letapples=3
  2. letoranges=5
  3. letappleSummary="Ihave(apples)apples."
  4. letappleSummary="Ihave(apples+oranges)piecesoffruit."

数组和字典
Swift使用[]操作符声明数组(array)和字典(dictionary):
[objc] view plain copy print ?
  1. varshoppingList=["catfish","water","tulips","bluepaint"]
  2. shoppingList[1]="bottleofwater"
  3. varoccupations=[
  4. "Malcolm":"Captain",
  5. "Kaylee":"Mechanic",
  6. ]
  7. occupations["Jayne"]="PublicRelations"

一般使用初始化器(initializer)语法创建空数组和空字典:
[objc] view plain copy print ?
  1. letemptyArray=String[]()
  2. letemptyDictionary=Dictionary<String,Float>()

如果类型信息已知,则可以使用[]声明空数组,使用[:]声明空字典。
控制流
概览
Swift的条件语句包含if和switch,循环语句包含for-in、for、while和do-while,循环/判断条件不需要括号,但循环/判断体(body)必需括号:
[objc] view plain copy print ?
  1. letindividualScores=[75,43,103,87,12]
  2. varteamScore=0
  3. forscoreinindividualScores{
  4. ifscore>50{
  5. teamScore+=3
  6. }else{
  7. teamScore+=1
  8. }
  9. }

可空类型
结合if和let,可以方便的处理可空变量(nullable variable)。对于空值,需要在类型声明后添加?显式标明该类型可空。
[objc] view plain copy print ?
  1. varoptionalString:String?="Hello"
  2. optionalString==nil
  3. varoptionalName:String?="JohnAppleseed"
  4. vargretting="Hello!"
  5. ifletname=optionalName{
  6. gretting="Hello,(name)"
  7. }

灵活的switch
Swift中的switch支持各种各样的比较操作:
[objc] view plain copy print ?
  1. letvegetable="redpepper"
  2. switchvegetable{
  3. case"celery":
  4. letvegetableComment="Addsomeraisinsandmakeantsonalog."
  5. case"cucumber","watercress":
  6. letvegetableComment="Thatwouldmakeagoodteasandwich."
  7. caseletxwherex.hasSuffix("pepper"):
  8. letvegetableComment="Isitaspicy(x)?"
  9. default:
  10. letvegetableComment="Everythingtastesgoodinsoup."
  11. }

其它循环
for-in除了遍历数组也可以用来遍历字典:
[objc] view plain copy print ?
  1. letinterestingNumbers=[
  2. "Prime":[2,3,5,7,11,13],
  3. "Fibonacci":[1,1,2,8],
  4. "Square":[1,4,9,16,25],
  5. ]
  6. varlargest=0
  7. for(kind,numbers)ininterestingNumbers{
  8. fornumberinnumbers{
  9. ifnumber>largest{
  10. largest=number
  11. }
  12. }
  13. }
  14. largest

while循环和do-while循环:
[objc] view plain copy print ?
  1. varn=2
  2. whilen<100{
  3. n=n*2
  4. }
  5. n
  6. varm=2
  7. do{
  8. m=m*2
  9. }whilem<100
  10. m

Swift支持传统的for循环,此外也可以通过结合..(生成一个区间)和for-in实现同样的逻辑。
[objc] view plain copy print ?
  1. varfirstForLoop=0
  2. foriin0..3{
  3. firstForLoop+=i
  4. }
  5. firstForLoop
  6. varsecondForLoop=0
  7. forvari=0;i<3;++i{
  8. secondForLoop+=1
  9. }
  10. secondForLoop

注意:Swift除了..还有…:..生成前闭后开的区间,而…生成前闭后闭的区间。
函数和闭包
函数
Swift使用func关键字声明函数:
[objc] view plain copy print ?
  1. funcgreet(name:String,day:String)->String{
  2. return"Hello(name),todayis(day)."
  3. }
  4. greet("Bob","Tuesday")

通过元组(Tuple)返回多个值:
[objc] view plain copy print ?
  1. funcgetGasPrices()->(Double,Double,Double){
  2. return(3.59,3.69,3.79)
  3. }
  4. getGasPrices()

支持带有变长参数的函数:
[objc] view plain copy print ?
  1. funcsumOf(numbers:Int...)->Int{
  2. varsum=0
  3. fornumberinnumbers{
  4. sum+=number
  5. }
  6. returnsum
  7. }
  8. sumOf()
  9. sumOf(42,597,12)

函数也可以嵌套函数:
[objc] view plain copy print ?
  1. funcreturnFifteen()->Int{
  2. vary=10
  3. funcadd(){
  4. y+=5
  5. }
  6. add()
  7. returny
  8. }

作为头等对象,函数既可以作为返回值,也可以作为参数传递:
[objc] view plain copy print ?
  1. funcmakeIncrementer()->(Int->Int){
  2. funcaddOne(number:Int)->Int{
  3. return1+number
  4. }
  5. returnaddOne
  6. }
  7. varincrement=makeIncrementer()
  8. increment(7)

[objc] view plain copy print ?
  1. funchasAnyMatches(list:Int[],condition:Int->Bool)->Bool{
  2. foriteminlist{
  3. ifcondition(item){
  4. returntrue
  5. }
  6. }
  7. returnfalse
  8. }
  9. funclessThanTen(number:Int)->Bool{
  10. returnnumber<10
  11. }
  12. varnumbers=[20,19,12]
  13. hasAnyMatches(numbers,lessThanTen)

闭包
本质来说,函数是特殊的闭包,Swift中可以利用{}声明匿名闭包:
[objc] view plain copy print ?
  1. numbers.map({
  2. (number:Int)->Intin
  3. letresult=33*number
  4. returnresult
  5. })

当闭包的类型已知时,可以使用下面的简化写法:
[objc] view plain copy print ?
  1. numbers.map({numberin33*number})

此外还可以通过参数的位置来使用参数,当函数最后一个参数是闭包时,可以使用下面的语法:
[objc] view plain copy print ?
  1. sort([1,12,2]){$0>$1}

类和对象
创建和使用类
Swift使用class创建一个类,类可以包含字段和方法:
[objc] view plain copy print ?
  1. classShape{
  2. varnumberOfSides=0
  3. funcsimpleDescription()->String{
  4. return"Ashapewith(numberOfSides)sides."
  5. }
  6. }

创建Shape类的实例,并调用其字段和方法。
[objc] view plain copy print ?
  1. varshape=Shape()
  2. shape.numberOfSides=7
  3. varshapeDescription=shape.simpleDescription()


通过init构建对象,既可以使用self显式引用成员字段(name),也可以隐式引用(numberOfSides)。
[objc] view plain copy print ?
  1. classNamedShape{
  2. varnumberOfSides:Int=0
  3. varname:String
  4. init(name:String){
  5. self.name=name
  6. }
  7. funcsimpleDescription()->String{
  8. return"Ashapewith(numberOfSides)sides."
  9. }
  10. }

使用deinit进行清理工作。
继承和多态
Swift支持继承和多态(override父类方法):
[objc] view plain copy print ?
  1. classSquare:NamedShape{
  2. varsideLength:Double
  3. init(sideLength:Double,name:String){
  4. self.sideLength=sideLength
  5. super.init(name:name)
  6. numberOfSides=4
  7. }
  8. funcarea()->Double{
  9. returnsideLength*sideLength
  10. }
  11. overridefuncsimpleDescription()->String{
  12. return"Asquarewithsidesoflength(sideLength)."
  13. }
  14. }
  15. lettest=Square(sideLength:5.2,name:"mytestsquare")
  16. test.area()
  17. test.simpleDescription()

注意:如果这里的simpleDescription方法没有被标识为override,则会引发编译错误。
属性
为了简化代码,Swift引入了属性(property),见下面的perimeter字段:
[objc] view plain copy print ?
  1. classEquilateralTriangle:NamedShape{
  2. varsideLength:Double=0.0
  3. init(sideLength:Double,name:String){
  4. self.sideLength=sideLength
  5. super.init(name:name)
  6. numberOfSides=3
  7. }
  8. varperimeter:Double{
  9. get{
  10. return3.0*sideLength
  11. }
  12. set{
  13. sideLength=newValue/3.0
  14. }
  15. }
  16. overridefuncsimpleDescription()->String{
  17. return"Anequilateraltriaglewithsidesoflength(sideLength)."
  18. }
  19. }
  20. vartriangle=EquilateralTriangle(sideLength:3.1,name:"atriangle")
  21. triangle.perimeter
  22. triangle.perimeter=9.9
  23. triangle.sideLength

注意:赋值器(setter)中,接收的值被自动命名为newValue。
willSet和didSet
EquilateralTriangle的构造器进行了如下操作:
1.为子类型的属性赋值。
2.调用父类型的构造器。
3.修改父类型的属性。
如果不需要计算属性的值,但需要在赋值前后进行一些操作的话,使用willSet和didSet:
[objc] view plain copy print ?
  1. classTriangleAndSquare{
  2. vartriangle:EquilateralTriangle{
  3. willSet{
  4. square.sideLength=newValue.sideLength
  5. }
  6. }
  7. varsquare:Square{
  8. willSet{
  9. triangle.sideLength=newValue.sideLength
  10. }
  11. }
  12. init(size:Double,name:String){
  13. square=Square(sideLength:size,name:name)
  14. triangle=EquilateralTriangle(sideLength:size,name:name)
  15. }
  16. }
  17. vartriangleAndSquare=TriangleAndSquare(size:10,name:"anothertestshape")
  18. triangleAndSquare.square.sideLength
  19. triangleAndSquare.square=Square(sideLength:50,name:"largersquare")
  20. triangleAndSquare.triangle.sideLength

从而保证triangle和square拥有相等的sideLength。
调用方法
Swift中,函数的参数名称只能在函数内部使用,但方法的参数名称除了在内部使用外还可以在外部使用(第一个参数除外),例如:
[objc] view plain copy print ?
  1. classCounter{
  2. varcount:Int=0
  3. funcincrementBy(amount:Int,numberOfTimestimes:Int){
  4. count+=amount*times
  5. }
  6. }
  7. varcounter=Counter()
  8. counter.incrementBy(2,numberOfTimes:7)

注意Swift支持为方法参数取别名:在上面的代码里,numberOfTimes面向外部,times面向内部。
?的另一种用途
使用可空值时,?可以出现在方法、属性或下标前面。如果?前的值为nil,那么?后面的表达式会被忽略,而原表达式直接返回nil,例如:
[objc] view plain copy print ?
  1. letoptionalSquare:Square?=Square(sideLength:2.5,name:"optional
  2. square")
  3. letsideLength=optionalSquare?.sideLength

当optionalSquare为nil时,sideLength属性调用会被忽略。
枚举和结构
枚举
使用enum创建枚举——注意Swift的枚举可以关联方法:
[objc] view plain copy print ?
  1. enumRank:Int{
  2. caseAce=1
  3. caseTwo,Three,Four,Five,Six,Seven,Eight,Nine,Ten
  4. caseJack,Queen,King
  5. funcsimpleDescription()->String{
  6. switchself{
  7. case.Ace:
  8. return"ace"
  9. case.Jack:
  10. return"jack"
  11. case.Queen:
  12. return"queen"
  13. case.King:
  14. return"king"
  15. default:
  16. returnString(self.toRaw())
  17. }
  18. }
  19. }
  20. letace=Rank.Ace
  21. letaceRawValue=ace.toRaw()

使用toRaw和fromRaw在原始(raw)数值和枚举值之间进行转换:
[objc] view plain copy print ?
  1. ifletconvertedRank=Rank.fromRaw(3){
  2. letthreeDescription=convertedRank.simpleDescription()
  3. }

注意:枚举中的成员值(member value)是实际的值(actual value),和原始值(raw value)没有必然关联。
一些情况下枚举不存在有意义的原始值,这时可以直接忽略原始值:
[objc] view plain copy print ?
  1. enumSuit{
  2. caseSpades,Hearts,Diamonds,Clubs
  3. funcsimpleDescription()->String{
  4. switchself{
  5. case.Spades:
  6. return"spades"
  7. case.Hearts:
  8. return"hearts"
  9. case.Diamonds:
  10. return"diamonds"
  11. case.Clubs:
  12. return"clubs"
  13. }
  14. }
  15. }
  16. lethearts=Suit.Hearts
  17. letheartsDescription=hearts.simpleDescription()

除了可以关联方法,枚举还支持在其成员上关联值,同一枚举的不同成员可以有不同的关联的值:
[objc] view plain copy print ?
  1. enumServerResponse{
  2. caseResult(String,String)
  3. caseError(String)
  4. }
  5. letsuccess=ServerResponse.Result("6:00am","8:09pm")
  6. letfailure=ServerResponse.Error("Outofcheese.")
  7. switchsuccess{
  8. caselet.Result(sunrise,sunset):
  9. letserverResponse="Sunriseisat(sunrise)andsunsetisat(sunset)."
  10. caselet.Error(error):
  11. letserverResponse="Failure...(error)"
  12. }

结构
Swift使用struct关键字创建结构。结构支持构造器和方法这些类的特性。结构和类的最大区别在于:结构的实例按值传递(passed by value),而类的实例按引用传递(passed by reference)。
[objc] view plain copy print ?
  1. structCard{
  2. varrank:Rank
  3. varsuit:Suit
  4. funcsimpleDescription()->String{
  5. return"The(rank.simpleDescription())of(suit.simpleDescription())"
  6. }
  7. }
  8. letthreeOfSpades=Card(rank:.Three,suit:.Spades)
  9. letthreeOfSpadesDescription=threeOfSpades.simpleDescription()
协议(protocol)和扩展(extension)
协议
Swift使用protocol定义协议:
[objc] view plain copy print ?
  1. protocolExampleProtocol{
  2. varsimpleDescription:String{get}
  3. mutatingfuncadjust()
  4. }

类型、枚举和结构都可以实现(adopt)协议:
[objc] view plain copy print ?
  1. classSimpleClass:ExampleProtocol{
  2. varsimpleDescription:String="Averysimpleclass."
  3. varanotherProperty:Int=69105
  4. funcadjust(){
  5. simpleDescription+="Now100%adjusted."
  6. }
  7. }
  8. vara=SimpleClass()
  9. a.adjust()
  10. letaDescription=a.simpleDescription
  11. structSimpleStructure:ExampleProtocol{
  12. varsimpleDescription:String="Asimplestructure"
  13. mutatingfuncadjust(){
  14. simpleDescription+="(adjusted)"
  15. }
  16. }
  17. varb=SimpleStructure()
  18. b.adjust()
  19. letbDescription=b.simpleDescription

扩展
扩展用于在已有的类型上增加新的功能(比如新的方法或属性),Swift使用extension声明扩展:
[objc] view plain copy print ?
  1. extensionInt:ExampleProtocol{
  2. varsimpleDescription:String{
  3. return"Thenumber(self)"
  4. }
  5. mutatingfuncadjust(){
  6. self+=42
  7. }
  8. }
  9. 7.simpleDescription

泛型(generics)
Swift使用<>来声明泛型函数或泛型类型:
[objc] view plain copy print ?
  1. funcrepeat(item:ItemType,times:Int)->ItemType[]{
  2. varresult=ItemType[]()
  3. foriin0..times{
  4. result+=item
  5. }
  6. returnresult
  7. }
  8. repeat("knock",4)

Swift也支持在类、枚举和结构中使用泛型:
[objc] view plain copy print ?
  1. //ReimplementtheSwiftstandardlibrary'soptionaltype
  2. enumOptionalValue{
  3. caseNone
  4. caseSome(T)
  5. }
  6. varpossibleInteger:OptionalValue=.None
  7. possibleInteger=.Some(100)

有时需要对泛型做一些需求(requirements),比如需求某个泛型类型实现某个接口或继承自某个特定类型、两个泛型类型属于同一个类型等等,Swift通过where描述这些需求:
[objc] view plain copy print ?
  1. funcanyCommonElements<T,UwhereT:Sequence,U:Sequence,T.GeneratorType.Element:Equatable,T.GeneratorType.Element==U.GeneratorType.Element>(lhs:T,rhs:U)->Bool{
  2. forlhsIteminlhs{
  3. forrhsIteminrhs{
  4. iflhsItem==rhsItem{
  5. returntrue
  6. }
  7. }
  8. }
  9. returnfalse
  10. }
  11. anyCommonElements([1,3],[3])


本文转自 Lucida的博客 感谢原作者

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读