更新:2018.05.24
整理了一下demo:SwiftDemo
is、as、Any、Anyobject、?、!
后面的先不说,在swift的基础语法方面,我最懵逼的就是这几个东西了,放在一块一起看一下。
1、is、as 类型检查
- 在swift中, 类型检查是一种检查实例类型的方式,同时也是让实例作为它的父类或子类的一种方式。
- Swift通过
is
、as
来实现类型检查。
直接上例子:
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 -> 我们定义了两个子类,人和狗,好朋友,在Person
和Dog
中分别添加了一个属性food
和master
,并且初始化。然后,我们终于要用到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为不确定的类型,提供了两种特殊别名,any
和anyobject
, -
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
类型,它是一个枚举类型,这个类型只有两个元素,None
和Some
。就是说,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
输出的是Optiona
l中的some
的值 123456