Проверка типов с помощью is
Проверяйте тип экземпляра перед приведением.
«Проверка типов с помощью is» — бесплатный урок Swift Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения 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
Используйте is в guard, чтобы сразу выйти, если экземпляр имеет не ожидаемый тип.
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"))Объединение is в switch
Проверять типы в 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; а проверка с помощью 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"), Dog(name: "Buddy")]
print("Cats:", zoo.filter { $0 is Cat }.count)
print("Dogs:", zoo.filter { $0 is Dog }.count)Часто задаваемые вопросы
Урок «Проверка типов с помощью is» бесплатный?
Да — полный текст урока «Проверка типов с помощью is» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Swift Academy, подпишись на CoddyKit PRO. Курс Swift Academy содержит 4 уроков всего.
Чему я научусь в уроке «Проверка типов с помощью is»?
Проверяйте тип экземпляра перед приведением. Ты практикуешь Swift Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Swift Academy?
Предыдущий опыт не требуется. Swift Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.
Сколько времени занимает урок «Проверка типов с помощью is»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Swift Academy?
Да. Каждый урок Swift Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Основы повышающего и понижающего приведения
- Условное приведение с помощью as?
- Принудительное приведение с помощью as! и его риски
- Проверка типов с помощью is