swift类型转换is和as

旧时模样 提交于 2020-05-02 10:52:09

Swift中类型转换使用 isas操作符。使用这两个操作符可以检查值的类型或者转换他的类型

一、类型检查

class Animal: NSObject {
    var name: String!
    init(name: String) {
        self.name = name
    }
}
class Dog: Animal {
    var color: UIColor!
    init(name: String,color: UIColor) {
        self.color = color
        super.init(name: name)
    }
}
class Cat: Animal {
    var weight: Float!
    init(name: String,weight: Float) {
        self.weight = weight
        super.init(name: name)
    }
}

let animals = [Dog.init(name: "tiger", color: UIColor.yellow),
Dog.init(name: "wangcai", color: UIColor.black),
Cat.init(name: "hellokitty", weight: 10.0)]

如上创建三个类: Animal,Dog,Cat ,其中Cat和Dog继承与Animal 。创建了一个容器,容器中有两个Dog和一个Cat的实例。

        var dogCount = 0
        var catCount = 0
        for animal in animals {
            if animal is Dog {
                dogCount += 1
            } else if animal is Cat {
                catCount += 1
            }
        }

如上在for 循环中使用  is  进行判断 -->若 animal 是 Dog 类型的实例返回 true,否则返回false (类似OC中的 isKindOfClass:

二、向下转型

某类型的一个常量或变量可能实际上属于一个子类。当确定是这种情况时,你可以尝试向下转到它的子类型,用类型转换操作符(as? 或 as!)。

因为向下转型可能会失败,类型转型操作符带有两种不同形式。条件形式(conditional form) as? 返回一个你 试图向下转成的类型的可选值(optional value)。强制形式 as! 把试图向下转型和强制解包(force-unwrap s)转换结果结合为一个操作。

当你不确定向下转型可以成功时,用类型转换的条件形式( as? )。条件形式的类型转换总是返回一个可选值(o ptional value),并且若下转是不可能的,可选值将是 nil 。这使你能够检查向下转型是否成功。

只有你可以确定向下转型一定会成功时,才使用强制形式( as! )。当你试图向下转型为一个不正确的类型 时,强制形式的类型转换会触发一个运行时错误。

 for animal in animals {
            if let dog = animal as? Dog {
                printLog("\(dog.name)")
            } else if let cat = animal as? Cat {
                printLog("\(cat.name)")
            }
        }

如上使用 as? 进行转换。尝试将animal 转换成 Dog或者Cat类型 如果成功则打印出动物的名字。

注意:转换并没有改变实例。原来的实例保持不变,只是将他作为被转换成的类型来使用。

(OC中的强制类型转换与它相似。如:一个数组中都是Dog的实例,要取出第一个实例可以这样写: Dog *dog = (Dog *)dogArray[0]

三、Any和AnyObject的类型转换

Swift 为不确定类型提供了两种特殊的类型别名:

• AnyObject 可以表示任何类类型的实例

• Any可以表示任何类型,包括函数类型。

注意:
只有当你确实需要它们的行为和功能时才使用Any和AnyObject。在你的代码里使用明确类型总是 更好的。

AnyObject类似OC的 id 类型,但是还是有区别的。具体可以参考 http://swifter.tips/any-anyobject/ 。

AnyObject类型

以下定义了一个[AnyObject]类型的数组,并放入了两个 Dog 的实例。

let animals: [AnyObject] = [Dog.init(name: "tiger", color: UIColor.yellow),
Dog.init(name: "wangcai", color: UIColor.black)]

因为知道这个数组只包含 Dog 实例,你可以直接用(as!)下转并解包到非可选的 Dog 类型:

 for animal in animals {
     let dog = animal as! Dog
     // ...
 }

也可以使用下面更简短的写法:

 for dog in animals as! [Dog] {
     // ...
 }

Any类型

下面的例子,使用 Any 类型来和混合的不同类型一起工作,包括函数类型和非类类型。它创建了一个可以存 储 Any 类型的数组 things :


 var things = [Any]()
 things.append(0)
 things.append(0.0)
 things.append(42)
 things.append(3.14159)
 things.append("hello")
 things.append((3.0, 5.0))
 things.append(Dog(name: "wangcai", color: UIColor.black))
 things.append({ (name: String) -> String in "Hello, \(name)" })

数组中包含了各种类型的值。

可以在 switch 表达式的 case 中使用 isas 操作符来找出只知道是 AnyAnyObject 类型的 常量或变量的具体类型。下面的示例迭代 things 数组中的每一项,并用 switch 语句查找每一项的类型。

for thing in things {
    switch thing {
    case 0 as Int:
        print("zero as an Int")
    case 0 as Double:
        print("zero as a Double")
    case let someInt as Int:
        print("an integer value of \(someInt)")
    case let someDouble as Double where someDouble > 0:
        print("a positive double value of \(someDouble)")
    case is Double:
        print("some other double value that I don't want to print")
    case let someString as String:
        print("a string value of \"\(someString)\"")
    case let (x, y) as (Double, Double):
        print("an (x, y) point at \(x), \(y)")
    case let dog as Dog:
        print("a dog called '\(dog.name)', color. \(dog.color)")
    case let stringConverter as String -> String:
        print(stringConverter("Michael"))
    default:
        print("something else")
} }

reference:swift官方教程中文版 ,http://swifter.tips/any-anyobject/ 。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!