使用 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 反馈 — 无需本地设置。
此课程中的所有课时
- 向上转型与向下转型基础
- 使用 as? 条件转型
- 使用 as! 强制转型及其风险
- 使用 is 检查类型