• 《Swift by Tutorials》学习笔记(第二章)


    第一章主要学习了Swift的一些基本内容,变量、常量、数据类型以及控制流。而这一章讲的是相对“高级”一点的基础知识,当然也还是基础知识啦。

    可选类型(Optionals)

    根据之前的知识,当我们需要声明一个变量的时候,我们可以这么做:

    var str = "Hello, playground"
    

    这样,我们在声明的时候同时指定了初值,但是,如果在有些情况下,你声明变量的时候是不知道初值的,那么应该怎么办呢?从直观上来讲,我们会这么做:

    // 声明一个字符串类型的变量,但没有赋初值
    var str: String
    

    实际上,如果我们这么做,编译器会报出 Variable 'str' used before being initialized 的错误, 在Swift当中,不允许声明一个变量而不赋值,这能防止我们在没有初始化的情况下使用
    变量。

    那么,如果这样呢?

    var str: String = nil
    

    结果,这次报出的错误是 Type ‘string’ does not conform to protocol ‘NilLiteralConvertible’str是一个字符串类型的变量,而nil不是一个字符串,所以我们不能进行赋值。

    事实上,在Swift当中,如果一个变量的值有可能为空,则我们需要指定它的类型为可选类型。

    可选类型的声明

    当我们需要声明一个可选类型的变量,我们可以这么做:

    var str: String?
    

    只需在变量类型的后面加一个问号就可以了。在没有赋初值的情况下,str会自动初始化为nil

    如果我们把声明改成如下:

    var str: String? = "Hello Swift by Tutorials"
    

    可以在右边的面板中看到输出结果为 {Some "Hello Swift by Tutorials!"},这说明str是一个可选类型,而非真正的字符串。

    在这种情况下,如果我们要使用str,则必须先对其进行解包,可以这么做:

    if let unwrappedStr = str {
        println("Unwrapped! (unwrappedStr.uppercaseString)")
    } else {
        println("Was nil")
    }
    

    当str的值不为nil时,则会将str解包,将直接赋值到unwrappedStr,然后执行第一个语句,否则会执行else里面的语句。

    强制解包(Forced unwrapping)

    当我们确定一个可选变量的值不为nil时,我们可以使用强制解包来获取变量内的值,而不必使用if语句来进行判断。要使用强制解包,只需要在变量的后面加一个感叹号:

    var str: String? = "Hello Swift by Tutorials!"
    println("Force unwrapped! (str!.uppercaseString")
    

    如果对一个值为nil的变量进行强制解包,会造成一个运行时错误。

    虽然强制解包很方便,但是它破坏了可选类型的安全性,只有当我们十分确定一个变量不是为nil时才能对它进行强制解包。

    隐式解包(Implict unwrapping)

    隐式解包功能可以让我们使用可选类型的时候不需要手动进行解包。要使用一个隐式解包的变量,我们需要在声明变量的时候不是使用问号,而是使用感叹号

    // 声明一个隐式解包的变量
    var str: String! = "Hello Swift by Tutorials"
    

    之后,我们可以像使用普通变量一样来使用str

    str = str.lowercaseString
    println(str)
    

    虽然,我们使用隐式解包变量的语法跟普通变量是一样的,但是实际是上编译器自己帮我们进行了解包,如果直接使用了一个值为nil的变量,还是会造成一个运行时的错误,所以在使用隐式解包变量的时候一定要注意。

    可选链(Optional chaining)

    使用可选链可以方便地获取一个可选变量的值,而不需要使用if/let的条件判断来对其进行解包。

    var maybeString: String? = "Hello Swift by Tutorials"
    let uppercase = maybeString?.uppercaseString
    

    第二行的问号,是可选链的语法。在运行的时候,编译器会先检查maybeString,如果它包含了正确的实例,则会继续执行uppercaseString语句,否则,则整个表达式返回nil。因此,uppercase也是一个可选类型的变量。

    集合类型

    任何一门语言里面都必然会包括集合类型。比如Objective-C中的NSArrayNSDictionary。Swift语言里面内置了两种数据类型,即数组和字典。

    数组

    数组是一组相同类型变量的集合,可以使用方括号来声明:

    var array = [1, 2, 3, 4, 5]
    

    在这里,编译器会进行类型推断,因为这个数组为Int类型的数组,也即,这个数组里面只能存储整型类型的数据。

    可以使用下标来获取特定位置的元素:

    println(array[2])
    

    也可以方便地向数组中添加元素:

    array.append(6)
    

    或者直接添加一组范围内的元素:

    array.extend(7...10)
    

    我们也可以显式地指定数组所能存储的类型:

    var array: [Int] = [1, 2, 3, 4, 5]
    

    在Swift当中有一个AnyObject类型,可以用来指代任何类型,如果我们声明了一个AnyObject类型的数组,则这个数组就可以存储任意类型的元素。虽然使用AnyObject看起来挺方便的,不过它破坏了Swift的类型安全机制,所以最好少用。

    字典

    数组存储的是一组类型的数据,而字典则存储的是一组键值对。

    var dictionary = [1: "Dog", 2: "Cat"]
    

    这行代码声明了一个包含两个键值对的字典,键和值之间使用分号隔开,而每个键值对之间使用逗号来分隔。

    与数组类似,我们也可以显示声明字典的类型:

    var dictionary: [Int: String] = [1: "Dog", 2: "Cat"]
    

    可以使用方括号配合键来获得特定的值:

    println(dictionary[1])
    

    也可以对值进行更新:

    dictionary[3] = "Mouse"
    println(dictionary)
    

    我们可以将某个值设为nil来删除它:

    dictionary[3] = nil
    

    上面的代码执行后,则字典里又只包含两个键值对。

    要注意到,当我们使用键来获取某个值的时候,返回的是一个可选值,因为我们要取的值有可能不包含在字典当中。

    // 输出Optional("Dog")
    println(dictionary[1])
    

    引用和拷贝

    在Swift当中,当我们对数组或者字典进行赋值,或者在函数进行传参的时候,编译器会当整个数组或字典进行拷贝,而并非只传递了引用,这与其它很多语言有很大的不同。

    var dictionaryA = [1: 1, 2: 4, 3: 9, 4: 16]
    var dictionaryB = dictionaryA
    
    dictionaryB[4] = nil
    println(dictionaryA)
    println(dictionaryB)
    

    运行之后可以看到,我们修改了字典B的元素,而字典A不会受到影响,因此可以证明在Swift当中字典确实是按值拷贝的。

    对数组进行同样的操作

    var arrayA = [1, 1, 2, 3, 5, 8, 13]
    var arrayB = arrayA
    
    arrayB.removeAtIndex(0)
    println(arrayA)
    println(arrayB)
    

    同样的,对数组B进行的操作不会影响到数组A。

    常量集合

    如果我们想使声明的集合类型为不可变的,只需要使用let关键字。

    let constantArray = [1, 2, 3, 4, 5]
    

    这样定义出来的数组将是不可变的,即不能修改元素的内容,也不能对数组进行增加和删除。

    小结

    这章主要讲了Swift当中的可选类型,可选类型是Swift当中比较独特的类型,也是用来保证Swift类型安全的重要类型,因此用到的地方会很多,有必要好好掌握。同时还介绍了Swift当中的两种集合类型,数组和字典,使用方法与其它语言也是大同小异的,因此也比较容易上手。

  • 相关阅读:
    mongodb 4.X 创建用户以及授权
    文件上传之后,MD5不一致,大小一致
    golang macaron各种形式入参封装
    说说非托管资源的回收
    layui数据表格批量删除
    除按钮外禁用所有表单项
    could not read Username for 'https://github.com': No error
    进入Web的殿堂与Django的初接触
    shell脚本中的小数运算
    js遍历数组时删除元素最终结果不对
  • 原文地址:https://www.cnblogs.com/buginux/p/4242116.html
Copyright © 2020-2023  润新知