В данной статье мы рассмотрим два ключевых слова, используемых в Swift, это inout и mutating. Inout позволяет модифицировать переданный в функцию аргумент и изменять его значение, в то время как mutating позволяет модифицировать значения свойств внутри структур или перечислений. В статье мы будем рассматривать примеры использования этих концептов и их взаимодействия для улучшения вашей кодовой базы.
Inout
inout — это ключевое слово, используемое в Swift для определения, что параметр функции может быть изменен внутри функции.
Это означает, что изменения, внесенные в параметр, будут видны и действительны и вне функции.
Например, следующая функция принимает два параметра типа Int, и меняет их местами:
func swapNumbers(a: inout Int, b: inout Int) {
let temp = a
a = b
b = temp
}
Вызовем нашу функцию следующим образом:
var a = 1
var b = 2
swapNumbers(a: &a, b: &b)
print(a, b) // 2 1
Обратите внимание, что когда вы передаете параметр в функцию с inout, вы должны использовать амперсанд (&) при передаче переменной. Так же запомните, inout нельзя использовать для констант или литералов.
Mutating
В Swift, структуры и перечисления являются значениями, а не ссылками, как в случае с классами. Это означает, что копия структуры или перечисления содержит точную копию всех ее значений. Это позволяет избежать проблем с изменением данных из нескольких мест и сохраняет предсказуемость кода. Подробнее про ссылочные типы и типы значений можно прочитать здесь: Value Type и Reference Type или чем стек отличается от кучи?
Однако иногда необходимо изменить свойства структуры или перечисления, для этого используется ключевое слово mutating.
mutating — это ключевое слово, используемое в языке Swift для определения методов или функций, которые могут изменять состояние структуры или перечисления.
Это означает, что внутренние поля или свойства объекта могут быть изменены во время выполнения метода или функции. В случае со структурами, изменения могут быть внесены как в свойства инстанса, так и в свойства самой структуры. В случае с перечислениями, изменения могут быть внесены только в свойства инстанса.
Например, у нас есть структура Site с приватными свойствами: домен и описание сайта. Если мы хотим написать метод, который будет изменять описание нашего сайта, то нам нужно объявить этот метод как mutating:
struct Site {
private(set) var domain: String
private(set) var description: String
init(domain: String, description: String) {
self.domain = domain
self.description = description
}
mutating func changeDescription(newDescription: String) {
self.description = newDescription
}
}
В этом примере, метод changeDescription объявлен как mutating. Это означает, что он может изменять свойство description структуры Site. Давайте запустим нашу программу:
var site = Site(domain: "www.ios-interview.ru", description: "Подготовка к собеседованию")
print(site.description) // Подготовка к собеседованию
site.changeDescription(newDescription: "Все для подготовки к собеседованию на iOS-разработчика")
print(site.description) // Все для подготовки к собеседованию на iOS-разработчика
Ключевые слова inout и mutating могут быть полезны для модификации существующих значений и создания более эффективного и удобного кода. Однако следует использовать их с осторожностью и учитывать их влияние на производительность и потенциальные проблемы с памятью.
Куда пойти дальше:
- Управление памятью в Swift
- Value Type и Reference Type или чем стек отличается от кучи?
- Механизм Copy-on-Write
- Mutating and non-mutating Swift contexts
- Функции высшего порядка для работы с коллекциями
Выразить благодарность или найти уникальный материал вы можете в boosty.
Подписывайтесь на мой Telegram-канал iOS Interview Channel, чтобы не пропустить новый материал.