0Pricing
Swift Academy · 课时

使用 is 检查类型

在转型前测试实例的类型。

使用 is 检查类型 是 CoddyKit 上的免费 Swift Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Swift Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Swift Academy 课程共包含 4 节课。

is 运算符

类型检查运算符 is 会返回一个 Bool,用于告知您实例是否属于给定类型(或其子类型)。它不会进行转型,只会执行检查。

class Animal {
    let name: String
    init(name: String) { self.name = name }
}
class Dog: Animal {
    func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
    func meow() -> String { return name + " says Meow" }
}
let a: Animal = Dog(name: "Rex")
print(a is Dog)
print(a is Cat)

检查是否属于子类型

当实例恰好是该类型或其任意子类的实例时,is 为 true。Dog 就是 Animal。

class Animal {
    let name: String
    init(name: String) { self.name = name }
}
class Dog: Animal {
    func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
    func meow() -> String { return name + " says Meow" }
}
let a: Animal = Dog(name: "Rex")
print(a is Animal)
print(a is Dog)

在条件中使用 is

您可以使用 if 对类型检查进行分支,根据运行时类型选择相应的行为。

class Animal {
    let name: String
    init(name: String) { self.name = name }
}
class Dog: Animal {
    func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
    func meow() -> String { return name + " says Meow" }
}
let a: Animal = Cat(name: "Mia")
if a is Cat {
    print("It is a cat")
} else {
    print("Not a cat")
}

统计集合中的类型数量

is 的一个实用场景是在混合数组中统计与某种类型匹配的元素数量。

class Animal {
    let name: String
    init(name: String) { self.name = name }
}
class Dog: Animal {
    func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
    func meow() -> String { return name + " says Meow" }
}
let zoo: [Animal] = [Dog(name: "Rex"), Cat(name: "Mia"), Dog(name: "Buddy")]
let dogCount = zoo.filter { $0 is Dog }.count
print("Dogs:", dogCount)

is 与协议

is 还可以测试实例是否遵循某个协议;如果遵循,则返回 true。

protocol Flyer {}
class Bird: Flyer {}
class Fish {}
let creatures: [Any] = [Bird(), Fish()]
for c in creatures { print(c is Flyer) }

is 与 as? 的区别

is 只能回答是或否。as? 更进一步:如果您需要使用子类成员,它会为您提供相应的值。

class Animal {
    let name: String
    init(name: String) { self.name = name }
}
class Dog: Animal {
    func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
    func meow() -> String { return name + " says Meow" }
}
let a: Animal = Dog(name: "Rex")
print("Check only:", a is Dog)
if let d = a as? Dog { print("Use it:", d.bark()) }

使用 is 进行防护

在 guard 中使用 is,可以在实例不是预期类型时及早退出。

class Animal {
    let name: String
    init(name: String) { self.name = name }
}
class Dog: Animal {
    func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
    func meow() -> String { return name + " says Meow" }
}
func onlyForCats(_ a: Animal) {
    guard a is Cat else {
        print("Skipping non-cat")
        return
    }
    print("Processing a cat")
}
onlyForCats(Cat(name: "Mia"))
onlyForCats(Dog(name: "Rex"))

在 switch 中组合使用 is

您可以间接地对类型检查使用 switch,不过在处理多种类型时,使用 case is 进行模式匹配更清晰易读。

class Animal {
    let name: String
    init(name: String) { self.name = name }
}
class Dog: Animal {
    func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
    func meow() -> String { return name + " says Meow" }
}
let items: [Any] = [Dog(name: "Rex"), 42, "hello"]
for item in items {
    switch item {
    case is Dog: print("a dog")
    case is Int: print("an integer")
    default: print("something else")
    }
}

is 检查运行时类型

is 检查的是实际的运行时类型,而不是变量声明的类型。类型标注为 Animal 且存放 Dog 的变量,会通过 is Dog 检查。

class Animal {
    let name: String
    init(name: String) { self.name = name }
}
class Dog: Animal {
    func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
    func meow() -> String { return name + " says Meow" }
}
let declaredAsAnimal: Animal = Dog(name: "Rex")
print("Runtime is Dog:", declaredAsAnimal is Dog)

强制转换前进行验证

一种安全的模式是先使用 is 检查,再使用 as!,因为此时您已经确认了类型。

class Animal {
    let name: String
    init(name: String) { self.name = name }
}
class Dog: Animal {
    func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
    func meow() -> String { return name + " says Meow" }
}
let a: Animal = Dog(name: "Rex")
if a is Dog {
    let d = a as! Dog
    print(d.bark())
}

类型检查综合示例

结合使用用于检查的 is 和用于转换的 as?,您就拥有了一套完整且安全的运行时类型工具。

class Animal {
    let name: String
    init(name: String) { self.name = name }
}
class Dog: Animal {
    func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
    func meow() -> String { return name + " says Meow" }
}
let zoo: [Animal] = [Dog(name: "Rex"), Cat(name: "Mia")]
for a in zoo {
    if a is Dog { print("dog:", a.name) }
    if a is Cat { print("cat:", a.name) }
}

快速检查

回想一下 is 运算符返回的内容。

回顾:使用 is 检查类型

您已经学会:is 会返回一个 Bool,用于检查运行时类型归属关系,包括子类和协议遵循关系;它适合与筛选以及 switch case is 搭配使用;在执行 as! 之前使用 is 检查,可以让强制类型转换变得安全。

class Animal {
    let name: String
    init(name: String) { self.name = name }
}
class Dog: Animal {
    func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
    func meow() -> String { return name + " says Meow" }
}
let zoo: [Animal] = [Dog(name: "Rex"), Cat(name: "Mia"), Dog(name: "Buddy")]
print("Cats:", zoo.filter { $0 is Cat }.count)
print("Dogs:", zoo.filter { $0 is Dog }.count)

常见问题解答

「使用 is 检查类型」课时是免费的吗?

是的 — 「使用 is 检查类型」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Swift Academy 课程的其余内容,请升级到 CoddyKit PRO。 Swift Academy 课程共包含 4 节课。

「使用 is 检查类型」这节课中我会学到什么?

在转型前测试实例的类型。 你通过在浏览器中直接运行的动手代码来练习 Swift Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Swift Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Swift Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。

「使用 is 检查类型」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Swift Academy 课中编写并运行代码吗?

能。每节 Swift Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 向上转型与向下转型基础
  2. 使用 as? 条件转型
  3. 使用 as! 强制转型及其风险
  4. 使用 is 检查类型
← 返回 Swift Academy