Swift入门基础1——元组、可选类型和循环

前言

本来之前计划是11月份开始学习Swift语言的,但是前段时间项目赶进度,加班厉害。所以计划没启动几天就搁置了,现在终于闲了下来,可以好好开始学习学习Swift了。Swift从苹果推出至今,已经出现了好几次比较大的版本更新,现在是Swift 3.0了,语法趋于稳定。而且Swift语言更简洁,更安全,更强大。它应该会越来越流行,最终取代OC作为iOS开发的第一语言。作为开发人员应当保持学习的激情,紧跟技术更新,不断学习积累。in one word,up or out.


元组

元组是OC中没有的一种新数据结构,它有点将数组和字典揉合的感觉,既像数组也像字典,使用起来极其灵活。
元组的初始化和使用都极其灵活,下面是些例子:

初始化时不申明元组类型,赋值时不申明元素名字。
此时则类似数组,可通过索引访问各个元素。但元组和数组不同的是,数组各项元素的类型必须一致,而元组不是,它的元素可以是任意类型。

        let a = ("wang66", "wangpsd", true)
        print("a---\(a)")
        print("a---\(a.0)")
        print("a---\(a.1)")
        print("a---\(a.2)")

初始化时申明元组类型,但赋值时不申明元素名字:
此时仍类似数组。只不过申明元组类型(各元素类型)使其看起来更清晰。

        let aa: (String, String, Bool) = ("wang66", "wangpsd", true)
        print("aa---\(aa)")
        print("aa---\(aa.0)")
        print("aa---\(aa.1)")
        print("aa---\(aa.2)")

初始化时不申明元组类型,但赋值时申明元素名字。
此时则类似字典,通过元素名字可访问其值。

        let b = (name:"wang66", passwd:"wangpsd", isLogin:true)
        print(b)
        print(b.name)
        print(b.passwd)
        print(b.isLogin)

初始化时申明元组类型,且赋值时申明元素名字

        let bb: (String, String, Bool) = (name:"wang", passwd:"wang", isLogin:true)
        print(bb)
        print(bb.0)
        print(bb.1)
        print(bb.2)

初始化时申明元素类型,且在元素类型里申明了元素名字。而且在赋值时带上了元素名字。

        let bbb: (name:String, passwd:String, isLogin:Bool) = (name:"wang", passwd:"wang", isLogin:false)
        print(bbb)
        print(bbb.0)
        print(bbb.passwd)
        print(bbb.isLogin)

初始化时申明元素类型,且在元素类型里申明了元素名字。但在赋值时没有写元素名字。
此时,仍旧可以通过元素名字得到值。

        let bbbb: (name:String, passwd:String, isLogin:Bool) = ("wang", "wang", false)
        print(bbbb)
        print(bbbb.name)
        print(bbbb.passwd)
        print(bbbb.isLogin)

还可以将元组当作一些变量/常量的合集来使用:

        let (name, passwd, isLogin) = ("wang", "wang", true)
        print(name)
        print(passwd)
        print(isLogin)
何处该用元组?

当你想让你的方法返回多个类型的多个值时,这是元组的最佳使用场景。如果返回的多个值类型是一致的,以往我们使返回类型为一个字典。但是若返回的多个值为不同的类型,以往我们可以将其封装为一个model,而有些时候感觉就几个数据并没有必要封装为model。在Swift中,元组可以完美地解决这个问题。

    func getStudentInfo() -> (name: String, age: Int, isPass: Bool) {
        let stuInfo = (name:self.stuName, age:self.stuAge, isPass: self.isPass)
        return stuInfo
    }

可选类型

可选类型(optionals),也是Swift的新特性。它表示** 可以有值,也可以没值;有值时为x,没值时便为nil。**
OC中也有nil,但是那只适用于对象,而Swift的可选类型却是适用于所有类型的,包括基本数据类型。

Swift之所以引进可选类型,主要是为了提高安全性。因为在代码中经常有些“未预期的变量为空”情况,在有些情况下很可能会程序crash掉,存在很大安全隐患。我们在写代码时为了避免出现这种安全问题,常常在代码中写入了了大量“防崩代码”,在调用方法前先判断调用者是否为空,在定义的方法内部判断参数是否为空等。
Swift就此做了努力,使这些可能为空的变量,在编译器编译时不予通过,将隐患扼杀在摇篮里。

下面先申明了一个字符串,但是没有初始化,然后打印该字符串。编译报错:❌variable 'str' used before being initialized。告诉我们str没有赋初值。

        var str: String
        print(str)

而我们将该字符串申明为可选类型后,便不会报错了。打印结果为nil。

        var str: String?
        print(str)

可选类型的拆包

Optional类型的值不能被直接使用,当需要用时要“拆包”,拆包有“显式拆包”“隐式拆包”

显式拆包:

所谓显式拆包,就是当变量用?申明未可选变量后。在使用变量时需要使用!来拆包, 获得它的值。

        var str: String? = "wang66"
        print(str!)

但这样一点也不安全,假如该str申明后没有被赋初值就拆包的话,编译可以通过,但是运行时会报错:❌unexpectedly found nil while unwrapping an Optional value

所以我们应当用if语句判断str,不为空时才进行拆包取值。注意:!=两侧都必须有空格,不然编译会报错:❌'=' must have consistent whitespace on both sides

        var str: String?
        if str != nil {
            print(str!)
        }else{
            print("str is nil")
        }
可选绑定:

像上面那样看起来不错了,但是也不完美。因为你在每次使用该变量时都被要求进行拆包。(虽然编译不会报错,但没有拆包,拿不到正确的值。会打印:Optional("1234"))。这是何其麻烦。

        var str: String?
        str = "1234"
        if str != nil {
            print(str!)
            print("str=\(str!)")
        }else{
            print("str is nil")
        }

为了避免每次使用变量时都要拆包,Swift引进了“可选绑定”:在if后面将可选变量赋给一个临时量,Swift会自动检测其是否包含值。若包含,则隐式拆包。那我们在后续便可以直接使用这个临时量了。
这个临时量既可以时常量let,也可以是变量var

        var str: String?
        str = "1234"
        if let tempStr = str{ // 将str赋给一个临时量,Swift会自动检测其是否包含值。若包含,则隐式拆包。
            print(tempStr)
        }
隐式可选类型的隐式拆包:

上面我们说了在申明变量/常量时,在类型后面加?表明它是个可选变量/常量。其实,Swift中还可以在类型后面加!,这代表什么呢?这代表它是个“隐式可选类型”。它是个可选类型,但是是隐式的。何谓隐式?就是我们在使用这个变量时就已确定它被初始化,不为nil了。我们每次直接使用变量,编译器会自动帮我们拆包。

        let str: String! = "wang66"
        print(str)

除非你真的确定你的变量已被初始化,不为nil。否则不要轻易使用“隐式拆包”,它也是有隐患的。
下面的代码也会报上面出现的错误:❌unexpectedly found nil while unwrapping an Optional value
str被置为nil了,然后编译器在自动拆包时,便蒙逼crash了。

        var str: String! = "wang66"
        str = nil
        print(str)
可选链式调用:

首先链式调用我们都知道,但是因为在Swift中有可选类型,这就导致了如果链式调用的某个环节,某个属性值为nil,某个方法返回值为nil,如果继续往链后面调用的话,会出问题的。所以为了避免这个问题,Swift是这样处理的。

class UserModel: NSObject {
    var userName: String?
    var address: String?
    var book: BookModel?
    func buy() {
        print("userName:\(userName), address:\(address), bookName:\(book?.bookName), price:\(book?.price)")
    }
}
class BookModel: NSObject {
    var bookName: String?
    var price: Double?
    func bookDesc() {
        print("bookName:\(bookName), price:\(price)")
    }
}

上面定义了两个类UserModelBookModel。两个类中的属性均为可选的,即有可能是空的。UserModel中的属性之一是BookModel类型的book。我们创建UserModel的实例user来通过链式语法来读写book属性。Xcode会自动帮我们在链中可能为nil的某实例后自动加上?作为处理,当非nil时,沿着链继续往后调用;若为nil,则返回nil,链式调用终止。

        let user = UserModel()
        user.book = BookModel()
        user.book?.bookName = "wanger"
        user.book?.price = 41.0
        user.book?.bookDesc()
        print("bookName:\(user.book?.bookName!)")

for-in循环

当我在swift中写出一个经典的for循环时,编译器报错了❌,而且是两个错误:
1.'++' is unavailable: it has been removed in Swift 3; 自增语法在swift3上废除了。
2.C-style for statement has been removed in Swift 3 C风格的循环写法在Swift3上废除了。

        let arr = ["wang11", "wang22", "wang33", "wang44"]
        
        for var i=0; i<10; i++
        {
            print(arr[i])
        }

看来循环语句不能这么写了。Swfit语句中只有for-in循环,但它完全够用了,可以取代经典的C写法。

        let arr = ["wang11", "wang22", "wang33", "wang44"]
        for item in arr {
            print(item)
        }

之所以说它可以取代C写法的for循环,是因为还可以这么写。(0...arr.count-1)“闭区间操作符”index的值在for循环执行的过程中,从闭区间的第一位取值,直到闭区间最后一位时循环结束。

        let arr = ["wang11", "wang22", "wang33", "wang44"]
        for index in (0...arr.count-1) {
            print(arr[index])
        }

(0...x)之所以叫闭区间,是因为首尾值都包括在内。Swift也提供了“半开半闭区间”(0..,是前闭后开的。还是上面的例子:

        let arr = ["wang11", "wang22", "wang33", "wang44"]
        for index in (0..

遍历字典的情况:将遍历出的每项字典元素赋给一个临时元组,后续使用时从元组中取值。

        let dict = ["wang11":24, "wang22":23, "wang33":25, "wang44":26]
        for (dictKey, dictValue) in dict {
            print("dictKey:\(dictKey)----dictValue:\(dictValue)")
        }

你可能感兴趣的:(Swift入门基础1——元组、可选类型和循环)