Swift中的as as? as!

前端之家收集整理的这篇文章主要介绍了Swift中的as as? as!前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

Swift是一门强类型语言,而Objective-C是弱类型语言(OC是动态性语言,让程序可以在运行时判断和决定其该有的行为,所以OC属于弱类型)。所以使用时需要注意对象之间关系,用is as as? as! 这些操作符来处理对象之间关系
Swift基于C和Objective-C,而却没有C的一些兼容约束。Swift采用了安全的编程模式。

本篇文章学习自泊学(boxueio.com)


类型的判断 - is

  1. is用来判断对象是否属于某个类 或者子类,相当于OC的:isKindOf
  2. 示例 - 1:
class Shape {}
class Rectangle: Shape {}
class Circle: Shape {}

let r = Rectangle()
let c = Circle()
let shapeArr: Array<Shape> = [r,c]

// 统计arr中各种形状的数量 is操作符; 用 A is B 这样的用法来判断对象类型
var totalRects: Int = 0
var totalCircles:Int = 0
shapeArr[0] is Rectangle
for s in shapeArr
{
    if s is Rectangle
    {
// ++totalRects
        totalRects += 1
    }else if s is Circle{
        totalCircles += 1
    }
}

此时totalRects和totalCircles打印结果均为1
另外:三个月前的shapeArr.dynamicType fix成了type(of: shapeArr)
++totalRects 修改totalRects += 1


类型转换 - as? as!

  1. 子类到父类的类型转换是自动完成的
  2. 父类到子类的转换通常是需要我们明确指定的,管这样的转换叫downcasting向下转型,在swift中用as关键字来完成这个操作
  3. as? 和 as!:
    as? 会转换成一个目标类型的optional
    as!在转换成功时直接返回一个目标类型,失败的时候会引发运行时错误。所以 当转换一定会成功时才使用as!
    示例 - 2:
shapeArr[0] as? Rectangle
shapeArr[0] as! Rectangle
shapeArr[0] as? Circle
// shapeArr[0] as! Circle // error

在playground可以看到 此时分别输出

Optional<Rectangle>
Rectangle
nil
  1. 除了用于downcasting父类到子类这样的转换,as还可以用于AnyObject的转换。 swift中用AnyObject表示任意类型的对象
    AnyObject as! Custom
    示例 - 3:
// 把示例 - 1 中的shapeArr该成:
let shapeArr: Array<AnyObject> = [r,c]

此时后面的转换依然成立
5. as
① 除了as!或as? 还可以使用as自身
② 当编译器也知道一定能转成功的时候可以用as

let rect = r as Rectangle // 如果此时用as!则会警告 forced cast of 'Rectangle' to same type has no effect

③ as可以直接用在switch case语句里,可以直接把对象转换成目标类型。相当于as!

let Box: Array<Any> = [  // Any, 表示任意一种类型
    3,3.14,"3.1415",r,{ return "I'm a closure" }
]

closure是一个类型,不是对象,所以用Any,不用AnyObject

for item in Box
{
    switch item
    {
    case is Int:                //print("\(item) is Int")
    case is Double:
        print("\(item) is Double")
    case is String:
        print("\(item) is String")
    case let rect as Rectangle: //print("\(rect)")
        print("\(item) is Rectangle")
    case let fn as () -> String:
        fn()
    default:
        print("out of Box")
    }
}

注释:
① is 还可以判断Any和其他类型的关系,类似isKindOf
② 在case的value binding里使用as,当item的类型是Rectangle时 就会自动地把结果绑定给rect,此时编译器也知道一定能转成功,所以此处相当于as!, -> let rect = item as Rectangle


protocol 与 is as as!as?

除了转换Any和AnyObject之外,is和as还可以用来判断某个类型是否遵从protocol的约定

  1. 判断某个类型是否遵从了protocol的约定
    把示例-1中的class Shape {} 改成: protocol Shape {}
Box[0] is Shape

此时值为false

  1. 使用as操作符,把对象转换成一个protocol类型
Box[3] as? Shape
type(of: (Box[3] as? Shape))
type(of: (Box[3] as! Shape))
Box[3] as! Shape
c as Shape

在playground看到,此时值分别为:

Rectangle
Optional<Shape>.Type
Rectangle.Type
Rectangle
Circle

由此可以看出:

当类型转换成功的时候,如果使用的是as!,swift会把转换结果变成对象的真实类型,而不是protocol; 而当使用as?进行类型转换时,得到的就会是一个目标类型的Optional

原文链接:https://www.f2er.com/swift/321474.html

猜你在找的Swift相关文章