Swift(八)is、as、Any、Anyobject、?、!

更新:2018.05.24

整理了一下demo:SwiftDemo


is、as、Any、Anyobject、?、!

后面的先不说,在swift的基础语法方面,我最懵逼的就是这几个东西了,放在一块一起看一下。

1、is、as 类型检查

  • 在swift中, 类型检查是一种检查实例类型的方式,同时也是让实例作为它的父类或子类的一种方式。
  • Swift通过 isas来实现类型检查。

直接上例子:
a -> 首先我们需要一个基类。

    class World {
        var name:String
        init(name:String) {
            self.name = name
        }
    }

b -> 够大吧,定义了一个World基类,里面有一个属性name并初始化init,然后我们还需要两个子类:

    class Person:World {
        var food:String
        init(name:String, food:String) {
            self.food = food
            super.init(name: name)
        }
        
    }
    
    class Dog:World {
        var master:String
        init(name:String, master:String) {
            self.master = master
            super.init(name: name)
        }
    }

我们要使用is

c -> 我们定义了两个子类,人和狗,好朋友,在PersonDog中分别添加了一个属性foodmaster,并且初始化。然后,我们终于要用到is了,在这之前,我们还需要搞一个数组来存放这两个类的实例,目的是使用is来判断每个类型的个数。

        let arr:[World] = [
            Dog.init(name: "Benben", master: "Li"),
            Person.init(name: "Li", food: "apple"),
            Dog.init(name: "Dandan", master: "Han"),
            Person.init(name: "Han", food: "orange"),
            Person.init(name: "Liu", food: "banana")
        ]
        
        var dogNum:Int = 0
        var personNum:Int = 0
        for item in arr {
            
            if item is Dog {
                dogNum += 1
            } else {
                personNum += 1
            }
        }
        
        print(dogNum)
        print(personNum)

d -> 首先我们创建了一个数组,里面有人也有狗,人和狗有各自的数量,然后我们通过for循环遍历数组,通过is关键字来判断是人还是狗,并输出各自的个数。

输出结果:2,3

我们要使用as

        for item in arr {
            
            if item is Dog{
                let dog = item as! Dog
                print("Dog:\(dog.name), master:\(dog.master)")
            } else {
                let person = item as! Person
                print("Person:\(person.name), food:\(person.food)")
            }
        }

#输出
Dog:Benben, master:Li
Person:Li, food:apple
Dog:Dandan, master:Han
Person:Han, food:orange
Person:Liu, food:banana

e -> 书上的例子不是这样写的,但我觉得这样写可能看的更清楚,还是这个for循环遍历,我们使用as关键字给item 转换成对应的类型。
这么来看的话就比较清除了,
is用来判断类实例属于哪个类型,
as负责将其转换成其对应的类型。

2. Any和Anyobject

  • 有点类似OC中的id,Swift为不确定的类型,提供了两种特殊别名,anyanyobject
  • Anyobject可以表示class类型的实例。
  • Any可以表示任何类型的实例。

前面我们定义数组时,如果数组中内容不确定,后面就加了Any

var arr = [Any]()

或者我们可以再多写一点:

        var objects = [Any]()
        
        objects.append(3)
        objects.append(3.141592653)
        objects.append("圆周率")
        
        for item in objects {
            switch item {
            case let someInt as Int:
                print("This is Int class \(someInt)")
            case let someDouble as Double:
                print("This is Double class \(someDouble)")
            default:
                print("This is String class \(item)")
            }
        }
#输出
This is Int class 3
This is Double class 3.141592653
This is String class 圆周率

3. ?和!

  • 在Swift中,我们用var来定义变量,但Swfit中并不会自动给变量赋初始值。 所以如果使用未赋值的变量就会报错。
  • 所以他们搞了一个?,告诉你,我也不知道这个变量是不是有值,或者是什么类型的值。
  • 当你确定了这个变量确实有值要怎么办?他们又搞了一个!,让你告诉系统,我确定这个变量有值,出了事情我负责,然后,如果这个值是空的,他们就给你报错,然后项目搞崩。气不气,气不气。
  • 我是这样理解的,然后我们来看一个Optional类型,它是一个枚举类型,这个类型只有两个元素,NoneSome。就是说,nil对应Optional.None
        var password : String?
        print(password?.characters.count)

a -> 第一行中,我们定义了一个password,右侧添加了?, 表示password变量属于Optional类型,他的值可能是String类型,也可能是nil请注意此时的password不是String类型,而是Optional类型,对于一个Optional类型的变量,如果未被初始化,他的默认值是nil

b -> 在第二行代码中,在password后面也加了一个,表示对password进行拆包,尝试获取Optional包中的String内容。

c -> 但因为password没有被赋值,所以最为Optional类型的password默认值为nil。此时会跳过characters.count语句,直接输出password的值,nil

当你使用!时,就表示你告诉编译器,你确定 password一定不是nil,但是password的值就是nil,所以系统会报错。

当我们给password进行赋值之后,

        var password : String?
        password = "123456"
        print(password!.characters.count)
#输出
6

就没有问题了


注意看图片中,password输出的是Optional中的some的值 123456

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容