美文网首页程序员swift
Swift 未完待续 ......

Swift 未完待续 ......

作者: J_mailbox | 来源:发表于2015-12-16 14:46 被阅读691次
    s.jpg
    Swift是苹果在2014年WWDC(苹果开发者大会)发布的新开发语言,并且就在前不久,也就是2015年12月4日那天进行了开源,开源当天Swift在GitHub上Star就超过1万,截止目前已经突破23000,这足以说明Swift是很受欢迎的,目前有很多国内公司新的项目上已经开始使用了Swift语言进行开发,相信在不久的将来,Swift的开发者将会更多,有关Swift语言苹果官方文档是这样介绍的:
    • Swift是一种全新的编程语言,你可以使用它编写iOS,OS X和watchOS应用程序.并且Swift结合了C和Object-C的优点,不受C兼容性的限制,且采用安全的编程模式并添加了很多新特性,这一切都将使编程更简单,更灵活,同时也更有趣.*

    ** 第一个程序: **

    //在屏幕上打印Hello world
    print("Hello world!")
    
    
    以上就是Swift的第一个程序,怎么样,是不是很简单,相比C语言,Swift它不需要main()函数,同时语句结尾也不需要分号.

    常量与变量

    let:用来定义常量,其特点是一经赋值则其值就不允许再修改

    ** 常量的定义: **

    //定义一个常量num,并且给其赋值为10
    let num = 10 
    //以下做法错误,常量一经赋值,就不再允许修改其值了
    num = 20
    
    
    var:用来定义变量,其特点和常量相反,赋值后仍然可以修改

    ** 变量的定义: **

    //定义一个变量num,并且给其赋值为10
    var num = 10
    //修改变量num的值为20
    num = 20
    
    

    类型安全与类型推断

    • Swift是一个类型安全的语言,其对数据类型要求异常严格,它会在编译你的代码时自动进行类型检查,如果发现类型不匹配,就会提示,这样就可以尽早的帮助开发者发现并修复错误,值得一提的是Swift中没有隐士转换,所以如果你要对不同类型的数据进行计算,则必须要显示的转换

    ** 类型转换: **

    //定义常量num1,并且给其赋值为10
    let num1 = 10
    //定义常量num2,并且给其赋值为20
    let num2 = 10.5
    //如果你这样计算,那么编译是不允许你通过的,因为num1与num2的类型不匹配
    let sum = num1 + num2 //错误
    //以下两种转换都是可以的
    let sum1 = num1 + Int(num2)
    let sum2 = Double(num1) + num2
    print(sum1,sum2)
    //打印结果:20 20.5
    
    
    • 因为有类型推断,所以我们定义常量或者变量的时候我们并不需要声明类型,因为系统会根据我们的字面量自动进行类型推断

    ** 定义常量并指定其类型: **

    //定义常量num,并指定该常量为Int类型
    let num: Int = 10
    
    

    可选类型Optional

    • 可选类型是在Swift中才有的,C 和Object-C 中都没有可选类型这个概念
    • 当我们定义变量的时,如果指定可选的,则说明该变量可以有一个指定类型的值,同时也可以是nil,如果要该变量参与运算,则必须为其"解包(unwrap)",因为只有解包后才能参与计算
    • 解包的时候需要在变量后添加一个"!", 并且要确保解包后的值不能为nil,否则程序还将出错
    • 或者是一个值,或者是没有值,当没有值时为nil

    ** 可选类型的定义与使用: **

    //定义一个常量num,并指定其为可选的,为其初始化为10
    let num:Int? = 10
    let sum = num! + 10 
    print(sum)
    //打印结果:
    //20
    
    //定义一个变量num,并指定其为可选的,变量可选项的默认值为nil
    var num:Int? 
    let sum = num! + 10
    print(sum)//程序运行将报错
    
    //错误信息:fatal error: unexpectedly found nil while unwrapping an Optional value(在解包的时候发现一个可选值为nil)
    
    

    ** 判断用户输入的是否是数字: **

    //判断用户输入的是否为数字
    let userInput = "10"
    var num = Int(userInput)
    
    if num != nil {
        print("您输入的数字为:\\(num!)")
    }else{
        print("您输入的不是数字")
    }
    //打印结果:
    //您输入的数字为:10
    
    
    ?? 运算符
    • ?? 运算符可以判断变量或者常量的值是否为nil,使用 ?? 判断如果其值为nil 那么系统则使用?? 后面的值替代.

    ** ??运算符的使用: **

    //定义变量num,并指定其为可选的,默认值为nil
    var num:Int? 
    //通过?? 判断,我们发现num为nil,因此num的值将由??后面的0替代
    let sum = (num ?? 0) + 10
    print(sum)
    //打印结果:
    //10
    
    

    区间运算符和 for in 循环

    • 和我们数学中学习的区间一样,区间运算符分为两类,一种是闭区间[a,b],表示a到b之间所有的值(包括b本身),一种是前闭后开区间[a,b),同样也表示a到b之间的值但是值得注意的是此时不报错b本身

    ** 闭区间与开区间的使用: **

    //闭区间
    for i in 1...10 {
       print(i) 
    }
    //i的值为:1 2 3 4 5 6 7 8 9 10
    
    //开区间
    for i in 1..<10 {
       print(i)
    }
    //i的值为:1 2 3 4 5 6 7 8 9 
    
    

    逻辑运算符

    布尔类型

    • 这里要注意,和OC中不同的是这里的Swift中的布尔类型的值不再是YES/NO,而且是true/false

    ** 布尔类型的使用: **

    var num = true
    var num2 = false
    if num {
        print("true")
    }else{
        print("false")
    }
    //打印结果:
    //true
    
    

    元组(Tuples)

    • 首先元组是Swift新引进的类型,在之前的OC中是没有的
    • 元组的实质就是将多个不同的值集合成一个数据
    • 其特点是可以有任意多个值,并且不同的值可以是不同的类型

    ** 元组的使用: **

    //声明一个元组并且初始化元组中的值
    let register = (status:true , name:"J_mailbox" , gender:"男" )
    
    //将我们上边定义的元组赋值给我们新声明的一个元组,这样的话我们就可以通过以下方式获取元组中每个元素的值了
    let (status, name, gender) = register
    print(status)//true
    print(name)//J_mailbox
    print(gender)//男
    
    print(register.0)//true
    print(register.1)//J_mailbox
    print(register.2)//男
    
    print(register.status)//true
    print(register.name)//J_mailbox
    print(register.gender)//男
    
    //以上三种写法都是可以的
    
    if register.status {
        print("注册成功!")
    }else{
        print("注册失败")
    }
    //打印结果:
    //注册成功!
    
    

    ** 使用"_"可以忽略元组中我们不关心的值 **

    
    //声明一个元组储存我们注册时的状态
    let connectionStatus = (true , "success")
    //通过 "_" 我们可以忽略我们不关心的值
    let (isSuccess , _ ) = connectionStatus
    //判断是否连接成功
    if isSuccess {
        print("连接成功!")
    }else{
        print("连接失败!")
    }
    //打印结果:
    //连接成功!
    
    

    if let

    • 为了避免可选项内容为nil导致的程序崩溃,我们可以使用if let 进行判断

    ** 使用if let 进行判断: **

    let num1:Int? = 10
    let num2:Int? = 20
    
    if  let n1 = num1,let n2 = num2 {
        print("num1:" + String(n1) + "\\nnum2:" + String(n2))
    }
    //打印结果:
    //num1:10
    //num2:20
    
    

    guard

    • guard是与if let 相反的语法

    ** guard的使用: **

    let num:Int? = 10
    
    guard let n1 = num else {
        print("num值为空")
    }
    
    

    字符串与字符

    • 实际开发中可以说我们是时时刻刻都在与字符串打交道,保存用户的信息,截取磁盘的路径,拼接一个完整的网络请求地址等等都离不开字符串,Swift中字符串和OC中基本一致,大致分为两大类:可变字符串和不可变字符串

    • 官方文档中是这样描述的:Swift 的String类型与 Foundation NSString类进行了无缝桥接,就像 AnyObject类型 中提到的一样,在使用 Cocoa 中的 Foundation 框架时,您可以将创建的任何字符串的值转换成NSString,并调用任意的NSString API.

    ** 字符串的初始化与判断: **

    //空字符串字面量
    var str = ""
    //实质是声明一个字符串类的对象
    var str2 = String()
    //以上两个字符串均为空并等价
    
    //判断当前字符串是否为空
    str.isEmpty  //true
    str2.isEmpty //true
    
    
    

    ** 字符串的可变性: **

    //字符串可变性
    //可变字符串
    var str = "Hello Swift"
    //不可变字符串
    let str2 = "J_mailbox"
    
    //正确
    str += "!"
    //错误,str2为不可变字符串
    str2 += "!"
    
    

    ** 字符串的遍历: **

    //字符串的遍历
    var str = "J_mailbox"
    
    //值得一提的是Swift 1.0版本中的遍历方法已经不能用了
    //for character in str {
    //  print(character)
    //}
    
    //Swift 2.0中使用以下方法
    for character in str.characters{
        print(character)
    }
    
    

    ** 字符串的拼接: **

    var str:String = "Hello "
    var str2:String = "J_mailbox"
    var str3:Character = "!"
    
    //正确,字符串之间连接可以通过 +=
    str += str2 //Hello J_mailbox 
    
    //str += str3 //错误,字符串和字符之间不可以使用 +=
    
    //字符串可以通过append连接字符
    str.append(str3) //Hello J_mailbox!
    
    
    

    ** 字符串的插值: **

    let str:String = "I am J_mailbox"
    let str2:String = "Swift"
    
    let str3 = "Hello, \\(str),I like \\(str2)" //Hello, I am J_mailbox,I like Swift
    
    

    ** 计算字符数量: **

    let str:String = "Hello Swift!"
    print(str.characters.count) //12
    
    

    ** 访问修改字符串: **

    let str:String = "Swift"
    //开始索引
    str.startIndex //0
    //字符串长度
    str.endIndex //5
    //根据索引获取索引所在位置上的字符
    str[str.startIndex] //S
    //通过查找字符串长度-1索引上的字符
    str[str.endIndex.predecessor()] //t
    //查找开始索引的下一个字符
    str[str.startIndex.successor()] //w
    //从开始索引起,第一个位置上的字符所在的索引
    let index = str.startIndex.advancedBy(1)
    str[index] //w
    
    //查找字符串长度上一个字符的索引(length -1)
    str.endIndex.predecessor() //4
    //获取字符串区间
    str.characters.indices //0..<5
    
    for index in str.characters.indices {
        print("\\(str[index]) ", terminator:"_")
    }
    //打印结果:
    //S_
    //w_
    //i_
    //f_
    //t_
    
    //以下两种方式都是越界错误,因此都是错误的
    //str[str.endIndex] //错误
    //str.endIndex.successor() //错误
    
    

    ** 插入和移除: **

    var str:String = "I am"
    //在am后添加空格
    str.insert(" ", atIndex: str.endIndex) //I am
    //在I am 后面添加J_mailbox!
    str.insertContentsOf("J_mailbox!".characters, at: str.endIndex) //I am J_mailbox!
    //移除最后一个!
    str.removeAtIndex(str.endIndex.predecessor()) //!
    //指定要删除的范围
    let range = str.startIndex.advancedBy(0)..<str.startIndex.advancedBy(5) //0..<5
    //从索引0开始删除到索引为5的位置
    str.removeRange(range) //J_mailbox
    //剩余字符串长度
    str.endIndex //9
    //移除全部
    str.removeAll() //""
    
    

    ** 字符串的比较: **

    let str1:String = "Hello Swift!"
    let str2:String = "Hello World!"
    
    //字典序比较,前面Hello 都相等,但是S < W
    if str1 < str2 {
        print("true")
    }else{
        print("false")
    }
    //结果:
    //true
    
    

    ** 前缀与后缀(hasPrefix/hasSuffix): **

    let str:String = "Hello world!"
    str.hasPrefix("!") //false
    str.hasSuffix("!") //true
    
    //定义一个数组,从该数组中查找数据库的个数
    let array = [
        "Language Swift",
        "Language Objective-C",
        "Language Java",
        "Language C#",
        "Language dephi",
        "DataBase Oracle",
        "DataBase SQL Server",
        "DataBase MySQL",
        "DataBase DB2",
        "DataBase SQLite"
    ]
    
    //遍历数组
    var DBCount = 0
    for db in array {
        if db.hasPrefix("DataBase") {
            DBCount++
        }
    }
    print("查找到的数据库为:\\(DBCount)个") // 5
    
    

    集合类型

    • Swift 提供了Arrays(数组)、Sets(集合)和Dictionaries(字典)三种基本的集合类型用来存储集合数据。数组(Arrays)是有序数据的集。集合(Sets)是无序无重复数据的集。字典(Dictionaries)是无序的键值对的集。
    集合类型.png

    ** 数组的基本使用 **

    • 数组使用有序列表存储同一类型的多个值。相同的值可以多次出现在一个数组的不同位置中。
    //创建一个空数组
    var array = [Int]()
    var array1 = Array<Int>()
    
    //初始化的数组最初元素个数为0
    print(array.count)
    
    //向数组中添加元素
    array.append(1)
    array.append(2)
    array.append(3)
    array.append(4)
    array.append(5)
    
    array.insert(6, atIndex: 5)
    
    //创建带默认数值的元素
    var array2 = [Int](count: 5, repeatedValue: 0)
    
    //数组的拼接(将array中的元素和array2中的元素合并到一个数组中)
    array = array + array2
    
    //判断数组是否为空
    array.isEmpty //false
    
    
    //字符串综合使用
    var strArray:[String] = ["Hello", "J_mailbox", "C++", "Python", "C#", "PHP"] //此时数组中元素分别为:Hello,J_mailbox,C++,Python,C#,PHP
    
    if !strArray.isEmpty {
        //添加新元素到strArray得数组末尾
        strArray.append("VB") //此时数组中元素分别为:Hello,J_mailbox,C++,Python,C#,PHP,VB
    }
    
    //添加新元素,Objective-C到数组strArray中
    strArray += ["JavaScipt"] //此时数组中元素分别为:Hello,J_mailbox,C++,Python,C#,PHP,JavaScript
    
    //元素替换
    strArray[0...1] = ["Java","C"] //此时数组中元素分别为:Java,C,C++,Python,C#,PHP,JavaScript
    
    //移除strArray数组中最后一个元素
    strArray
    strArray.removeAtIndex(strArray.count-1) //"Java", "C", "C++", "Python", "C#", "PHP", "VB"
    strArray.removeAtIndex(strArray.endIndex.predecessor()) //"Java", "C", "C++", "Python", "C#", "PHP"
    strArray.removeLast() //"Java", "C", "C++", "Python", "C#"
    
    print("2015年12月语言排行榜前五名分别为:")
    for Language in strArray {
        print(Language)
    }
    //打印结果:
    //Java
    //C
    //C++
    //Python
    //C#
    
    for (index, value) in strArray.enumerate() {
        print("2015年12月语言排行榜第\\(String(index + 1))名:\\(value)")
    }
    
    //打印结果:
    //2015年12月语言排行榜第1名:Java
    //2015年12月语言排行榜第2名:C
    //2015年12月语言排行榜第3名:C++
    //2015年12月语言排行榜第4名:Python
    //2015年12月语言排行榜第5名:C#
    
    

    ** 集合(Sets)的基本使用: **

    • 集合(Set)用来存储相同类型并且没有确定顺序的值。当集合元素顺序不重要时或者希望确保每个元素只出现一次时可以使用集合而不是数组。

    ** 集合的插入、移除、遍历: **

    var strSet = Set<String>()
    
    strSet.insert("H")
    strSet.insert("E")
    strSet.insert("L")
    strSet.insert("L")
    strSet.insert("O")
    
    strSet = [] //清空集合
    
    var strSet2:Set<String> = ["Hello", "Swift", "J_mailbox"]
    
    strSet2.count //3
    strSet2.isEmpty //false
    
    //插入元素Objective-C
    strSet2.insert("Objective-C") //目前strSet2中有4个元素
    
    //移除元素Hello
    strSet2.remove("Hello") //目前strSet2中有3个元素
    
    //判断集合中是否包含某一个值
    strSet2.contains("J_mailbox") //true
    
    //遍历一个集合
    for str in strSet2 {
        print("\\(str)")
    }
    //打印结果:
    //Objective-C
    //J_mailbox
    //Swift
    
    //排序
    var strSet3:Set<String> = ["A","B","C","D","E"]
    for str in strSet3.sort() {
        print(str)
    }
    //打印结果:
    //A
    //B
    //C
    //D
    //E
    
    

    ** UNION、INTERSECT、SUBTRACT、EXCLUSIVEOR 的基本集合使用: **

    集合关系图.png
    let num1:Set = [1, 3, 5, 7, 9, 100]
    let num2:Set = [2, 4, 6, 8, 10, 100]
    
    //根据两个集合里面的值创建一个新的集合(重复值只取一个)
    num1.union(num2).sort()
    //根据两个集合中都存在的值创建一个新的集合
    num1.intersect(num2).sort()
    //根据不在该集合中的值创建一个新的集合
    num1.subtract(num2).sort()
    //根据在一个集合中但不在两个集合中的值创建一个新的集合
    num1.exclusiveOr(num2.sort())
    
    

    ** 集合成员关系和相等: **

    集合关系图-2.png
    let str1:Set = ["H", "E", "L", "L", "O", "S", "W", "I", "F", "T"]
    let str2:Set = ["S", "W", "I", "F", "T"]
    let str3:Set = ["H", "E", "L", "L", "O"]
    
    //判断两个集合中的值是否相同
    str1 == str3 //false
    //判断一个集合(str1)中的值是否也被包含在另一个集合(str2)中
    str1.isSubsetOf(str2) //false
    //判断一个集合(str1)中是否包含另一个集合(str2)中的所有值
    str1.isSupersetOf(str2) //true
    //判断两个集合是否不含有相同的值
    str1.isDisjointWith(str2) //false
    //判断一个集合(str2)是否是另一个集合(str1)的子集合,并且两个集合并不相等
    str2.isStrictSubsetOf(str1) //true
    //判断一个集合(str1)是否是另一个集合(str2)的父集合,并且两个集合并不相等
    str1.isStrictSupersetOf(str2) //true
    
    

    字典

    • Swift 的字典使用Dictionary<Key, Value>定义,其中Key是字典中键的数据类型,Value是字典中对应于这些键所存储值的数据类型。

    ** 字典的基本使用: **

    //定义一个空字典
    var dict = [Int: String]()
    
    dict[1] = "Swift"
    dict[2] = "J_mailbox"
    
    print(dict) //[2: "J_mailbox", 1: "Swift"]
    
    var dict2:[String: String] = ["name": "J_mailbox", "age": "25"]
    dict2["height"] = "175.cm"
    dict2["weight"] = "60kg"
    
    print(dict2) //["height": "175.cm", "age": "25", "weight": "60kg", "name": "J_mailbox"]
    
    //更新某个值
    if let oldAge = dict2.updateValue("30", forKey: "age") {
        print("oldAge is \\(oldAge)") //25
    }
    print("newAge is \\(dict2["age"]!)") //30
    
    //移除某个值
    if let removedValue = dict2.removeValueForKey("name") {
        print("移除的name的值为:\\(removedValue)") //J_mailbox
    }
    
    //字典遍历(元组)
    for (key, value) in dict2 {
        print("key=\\(key),value=\\(value)")
    }
    //打印结果:
    //key=height,value=175.cm
    //key=age,value=30
    //key=weight,value=60kg
    
    //通过keys遍历字典
    for key in dict2.keys {
        print("key=\\(key)")
    }
    //打印结果:
    //key=height
    //key=age
    //key=weight
    
    //通过values遍历字典
    for value in dict2.values {
        print("value=\\(value)")
    }
    //打印结果:
    //value=175.cm
    //value=30
    //value=60kg
    
    
    
    

    控制语句

    • Swift 提供了类似 C 语言的流程控制结构,包括可以多次执行任务的for和while循环,基于特定条件选择执行不同代码分支的if、guard和switch语句,还有控制流程跳转到其他代码的break和continue语句.
    • Swift中可以使用for-in循环对一个集合里面的每个元素执行一系列语句

    ** for 循环的简单使用: **

    for index in 1...5 {
        print("index=\\(index)")
    }
    //打印结果:
    //index=1
    //index=2
    //index=3
    //index=4
    //index=5
    
    
    for var index = 0; index < 5 ;index++ {
        print("index is \\(index)")
    }
    打印结果:
    //index is 0
    //index is 1
    //index is 2
    //index is 3
    //index is 4
    
    
    let dictInfo = ["name": "J_mailbox", "age": 25]
    for (key ,value) in dictInfo {
        print("key is \\(key),value is \\(value)")
    }
    //key is age,value is 25
    //key is name,value is J_mailbox
    
    

    ** while 与 repeat: **

    
    var i = 0
    var j = 5
    //当条件满足的时候就会执行大括号中的代码
    while i < j {
        i++
    }
    //打印结果:
    //0
    //1
    //2
    //3
    //4
    
    //先执行一次大括号中的代码,在判断条件(和其他语言中的do-while语句类似)
    repeat {
        print("true")
    } while i > j
    //打印结果:
    //true
    

    ** Swift允许在使用switch语句的时候不写break: **

    //Swift 允许在使用switch语句的时候不写break
    let num:Int = 3
    switch num {
        case 1:
        print("1")
    case 2:
        print("2")
    case 3:
        print("3")
    case 4:
        print("4")
    default:
        print("No found")
    }
    //打印结果:
    //3
    
    
    

    ** 利用元组特性,判断某一个值是否在某个区间内: **

    //设定点区间
    let num = (1, 1)
    switch num {
        case (0, 0):
        print("坐标点为(0, 0)")
        case (_, 0):
        print("坐标点区间在(_, 0)之间")
        case (0, _):
        print("坐标点区间在(_, 0)之间")
        case (-2...2, -2...2):
        print("坐标点在(-2...2, -2...2)区间之内")
    default:
        print("范围内不存在此坐标点")
    }
    //打印结果:
    //坐标点在(-2...2, -2...2)区间之内
    
    

    ** 判断输入的数字是否是合法月份: **

    let strNum = (5)
        switch strNum {
        case (1...3):
            print("春季")
            break;
        case (4...6):
            print("夏季")
            break;
        case (7...9):
            print("秋季")
            break;
        case (10...12):
            print("冬季")
            break;
        default:
            print("不是合法月份")
    }
    //打印结果:
    //夏季
    
    

    ** break 与 continue 的对比: **

    
    for var i = 0; i<10; i++ {
        
        if i%10 == 0{
            break
            //continue;
        }
        print(i)
    }
    
    //运行之后对比可知:当使用break的时候,程序执行到break时会立刻中断循环体的执行并跳出循环,而使用continue的时候,循环体会立即停止本次循环的迭代,程序将打印出i的值,紧接着重新开始下次循环
    
    
    

    函数

    • 函数是用来完成特定任务的独立的代码块
    • Swift 统一的函数语法足够灵活,可以用来表示任何函数,包括从最简单的没有参数名字的 C 风格函数,到复杂的带局部和外部参数名的 Objective-C 风格函数
    • 格式: func 函数名(形参列表) -> 返回值 {代码实现}
    • 调用: let result = 函数名(实参列表)

    ** 函数的定义与调用: **

    
    //没有返回值的函数,三种写法
    
    //第一种
    func say(str: String) -> Void {
        print("str")
    }
    
    //第二种
    func say(str: String) -> () {
        print("str")
    }
    
    //第三种
    func say(str: String) {
        
    }
    

    ** 函数的四种表现形式: **

    //无参无返回值
    func sayHello () -> () {
        print("Hello")
    }
    
    //无参有返回值
    func sayHello () -> (Int) {
        return 0
    }
    
    //有参无返回值
    var sum = 0
    func sayHello (num1:Int, num2:Int) -> () {
        sum = num1 + num2
        print(sum) //8
    }
    //函数的调用
    sayHello(3, num2: 5)
    
    
    //有参有返回值
    func sayHello ( num1:Int, num2:Int) -> (Int) {
        return num1 + num2
    }
    //调用并打印
    print(sayHello(3, num2: 5))
    //打印结果:
    //8
    
    
    //函数的定义
    func sayHello (name:String) ->String {
        let say = "Hello," + name + "!"
        return say
    }
    
    //函数的调用
     print(sayHello("J_mailbox"))
    //打印结果:
    //Hello,J_mailbox!
    
    

    ** 使用可选元组类型让多个值作为一个复合值从函数中返回: **

    //通过元组比较数组中最大值最小值
    func minMax(array: [Int]) ->(min:Int, max:Int)? {
        if array.isEmpty { return nil }
        var min = array[0]
        var max = array[0]
        //遍历
        for value in array[1..<array.count] {
            if value < min {
                min = value
            }else if value > max {
                max = value
            }
        }
        return (min, max)
    }
    
    //var result = minMax([1,4,6,2,8,5,0,9])
    
    if let result = minMax([1,4,6,2,8,5,0,9]) {
        print("数组中最大值为:\\(result.max),最小值为:\\(result.min)")
    }else {
        print("数组为nil")
    }
    //打印结果:
    //数组中最大值为:9,最小值为:0
    
    

    ** 计算任意多个数字的平均值: **

    func avg (num: Double...) -> Double {
        //声明一个sum变量,用来存储所有数值的总和
        var sum: Double = 0
        for v in num {
            sum += v
        }
        print(sum)
        //计算平均值
        return sum / Double(num.count)
    }
    
    //调用函数
    print(avg(1, 3, 7, 9, 5, 4, 2, 1))
    //打印结果:
    //4.0
    
    

    闭包

    • 闭包和OC中得Block类似,它可以在特定的场景中对代码进行优化,比如利用上下文推断参数和返回值类型而不像函数必须指定相应的参数类型和返回值类型,在单独的表达式中闭包可以省略return,对参数名也可以进行简写,使代码更加紧凑,并且随着Swift的开源,很多第三方框架中也开始越来越多的使用闭包,因此掌握了闭包,它可以使你的编码更加高效

    ** 使用闭包对数字进行排序: **

    var arr:[Int] = [1, 5, 3, 6, 9, 0, 4, 2, 8, 7]
    //升序
    arr.sort() //[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    
    //比较两个值的大小
    func compare(a:Int, b:Int) ->Bool {
        return a>b
    }
    //降序
    arr.sort(compare) //[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
    
    //使用闭包的方式对数组中所有的元素进行降序排列
    arr.sort({(a:Int, b:Int)->Bool in
        return a > b
    })
    //最后结果:
    //[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
    
    

    ** 使用闭包对字符串进行排序: **

    //使用闭包对字符串进行排序
    var strArr = ["acd","dc","abd","abc","bcd","ba","bca","ab"]
    
    func compare(s1:String, s2:String) ->Bool {
        return s1 < s2
    }
    var result = strArr.sort(compare) //["ab", "abc", "abd", "acd", "ba", "bca", "bcd", "dc"]
    
    //也可以直接这样简写
    result = strArr.sort({(s1:String, s2:String)->Bool in
        return s1 < s2
    })
    
    //还可以对以上代码进行简化,如下写法也是可以的
    result = strArr.sort({(s1:String, s2:String) ->Bool in return s1 < s2 })
    
    //最后的结果:
    ["ab", "abc", "abd", "acd", "ba", "bca", "bcd", "dc"]
    

    ** 通过Swift中提供的上下文类型,我们还可以对上面的代码进行简化: **

    • 因为排序闭包函数是作为sort()方法的参数传入的,Swift可以自动推断出参数和返回值的类型,因此我们可以把参数类型和返回值类型都省略.
    //通过上下文类型推断进行字符串的排序简化
    result = strArr.sort({ s1, s2 in return s1 < s2 } )
    
    

    ** 单表达式闭包可以省略return: **

    • 根据之前我们提到的Swift中单行表达式闭包可以通过省略return关健字来隐式返回单行表达式的结果特性,我们还可以把return省略掉 **
    //省略return
    result = strArr.sort({ s1, s2 in s1 < s2 })
    
    

    ** 参数名称缩写: **

    • Swift中还自动为内联闭包提供了参数名称缩写功能,因此我们还可以通过$0 $1 $2 来顺序调用闭包的类型,因此我们还可以对上面的代码进行再一步简化,同时由于此时的闭包表达式完全由闭包函数体构成,因此in关健字同样可以省略:
    //参数名称缩写,同时省去in关键字
    result = strArr.sort({ $0 < $1 })
    
    

    ** 运算符函数: **

    //运算符函数,括号中直接写运算符即可(Swift可以自动推断出)
    result = strArr.sort(<)
    

    ** 尾随闭包的使用: **

    • 当我们需要将一个很长的闭包表达式作为最后一个参数传递给函数时,我们也可以使用尾随闭包来增加函数的可读性,
    //定义一个数组,里面存放这中英文对比的信息
    let arrStr = [
        0: "Zero", 1: "One", 2: "Two",   3: "Three", 4: "Four",
        5: "Five", 6: "Six", 7: "Seven", 8: "Eight", 9: "Nine"
    ]
    let nums = [123, 456, 69, 80]
    print(nums)
    //打印结果:
    [123, 456, 69, 80]
    
    //使用尾随闭包打印数组中元素对应的英文
    let str = nums.map {
        (var num) -> String in
        var output = ""
        while num > 0 {
        output = arrStr[num % 10]! + output
        num /= 10
        }
        return output
    }
    print(str)
    //打印结果:([123, 456, 69, 80])
    //["OneTwoThree", "FourFiveSix", "SixNine", "EightZero"]
    
    

    枚举

    • Swift 中的枚举更加灵活,不必给每一个枚举成员提供一个值.如果给枚举成员提供一个值(称为“原始”值),则该值的类型可以是字符串,字符,或是一个整型值或浮点数.
    • 枚举成员可以指定任意类型的关联值存储到枚举成员中.
    • 与 C 和 Objective-C 不同,Swift 的枚举成员在被创建时不会被赋予一个默认的整型值.
    • 相反,这些枚举成员本身就是完备的值,这些值的类型是已经明确定义好的类型.
    //多个成员可以出现同一行上,中间用逗号隔开
    enum weekDay {
        case Monday,Tuesday,Wednesday,Thursday,Firday,Saturday,Sunday
    }
    //星期一
    var monday = weekDay.Monday
    //也可以这么写
    //monday = .Monday
    
    switch monday {
    case .Monday:
        print("星期一")
    case .Tuesday:
        print("星期二")
    case .Wednesday:
        print("星期三")
    case .Thursday:
        print("星期四")
    case .Firday:
        print("星期五")
    case .Saturday:
        print("星期六")
    case .Sunday:
        print("星期日")
    }
    
    

    ** 本文参考Swift 2.0官方文档,采用Xcode 7.1编写,其中有些语法和方法的调用相比Swift 1.0版本变化的还是挺大的,如果有歧义的地方,还请依照官方文档为准. **

    总结:以上就是对Swift的基础知识的介绍,虽然都是基础,但是也是我们作为开发者必须要掌握的,因为只有我们牢牢的把这些基础掌握,以后我们使用Swift开发起来才会更加的得心应手,正所谓不积跬步,无以至千里;不积小流,无以成江海. 未完待续...

    相关文章

      网友评论

        本文标题:Swift 未完待续 ......

        本文链接:https://www.haomeiwen.com/subject/hrpuhttx.html