Параметры функций и читаемость API в Swift
Идея «вызов как фраза»
Напоминание: общие понятия функций в программе — функции в коде.
В Swift имя функции при вызове часто складывается из меток параметров. Это не декорация: метки входят в идентификатор метода и делают код похожим на осмысленное предложение.
func move(from start: Point, to end: Point) { /* ... */ }
move(from: origin, to: destination)
Сравните с вызовом без меток: move(origin, destination) — короче, но при шести параметрах читаемость падает. Apple API (UIKit, SwiftUI, Foundation) последовательно используют метки — привыкание к ним облегчает чтение документации и чужого кода.
Внешнее и внутреннее имя
У каждого параметра (кроме особых случаев) могут быть:
- внешнее имя — видно при вызове;
- внутреннее имя — используется в теле функции.
func greet(person name: String, times count: Int) {
for _ in 0..<count {
print("Hello, \(name)")
}
}
greet(person: "Мария", times: 3)
Здесь person и times — внешние, name и count — внутренние.
Если внешнее имя не указано, по умолчанию оно совпадает с внутренним. Первый параметр метода экземпляра (instance method) по соглашению не имеет внешней метки, если не задана явно — поэтому array.append(element) выглядит естественно.
Подчёркивание _ — скрыть метку
Когда метка при вызове только мешает:
func add(_ a: Int, _ b: Int) -> Int { a + b }
add(2, 3)
Используйте _ осознанно: для «математических» функций и оператороподобных методов. Для публичного API библиотеки чаще оставляют метки — так проще искать вызовы и понимать аргументы.
Значения по умолчанию
Параметр с default можно не передавать:
func connect(host: String, port: Int = 443, useTLS: Bool = true) { /* ... */ }
connect(host: "api.example.com")
connect(host: "legacy.example.com", port: 8080, useTLS: false)
Правила:
- параметры с default обычно идут после обязательных;
- при вызове пропущенные аргументы подставляются из объявления;
- default вычисляется в момент вызова (важно для
Date(), случайных значений).
Вариадические параметры
Функция может принять произвольное число однотипных аргументов через ...:
func sum(_ numbers: Int...) -> Int {
numbers.reduce(0, +)
}
sum(1, 2, 3, 4)
Внутри тела numbers — это массив ([Int]). Вариадический параметр, как правило, один на функцию и стоит последним среди обычных параметров (до inout).
Параметры inout
По умолчанию аргументы в Swift передаются по значению (для value types — копия). Чтобы функция могла изменить переменную вызывающего, используется inout:
func swapValues(_ a: inout Int, _ b: inout Int) {
let temp = a
a = b
b = temp
}
var x = 1, y = 2
swapValues(&x, &y)
При вызове обязателен префикс &. Это явный сигнал: «здесь возможен побочный эффект». Нельзя передать let или литерал — только изменяемую переменную.
inout не делает параметр ссылочным типом в смысле class: для структур по-прежнему работает copy-on-write у контейнеров, но сама переменная в области видимости вызывающего обновится.
Trailing closure — замыкание последним аргументом
Если последний параметр — замыкание, его можно вынести за скобки:
func perform(task: String, handler: () -> Void) {
print(task)
handler()
}
perform(task: "backup") {
print("done")
}
При нескольких замыканиях trailing применяют к последнему; остальные — в скобках (в Swift 5.3+ — множественные trailing closures для DSL, например SwiftUI).
Связь с управляющими конструкциями и коллекциями:
let ids = users.filter { $0.isActive }.map { $0.id }
Здесь $0 — сокращённый аргумент замыкания; полная форма: { user in user.id }.
Тип функции как значение
Сигнатура (Parameters) -> ReturnType — полноценный тип:
func apply(_ value: Int, using operation: (Int) -> Int) -> Int {
operation(value)
}
let double: (Int) -> Int = { $0 * 2 }
apply(10, using: double)
Так задают колбэки, стратегии сортировки, обработчики событий. В современном коде часть колбэков заменена на async/await (асинхронность), но типы функций остаются в стандартной библиотеке (sort, map).
Вложенные и возвращающие функции
Функция может быть объявлена внутри другой — доступ к локальным переменным внешней:
func makeCounter() -> () -> Int {
var count = 0
func increment() -> Int {
count += 1
return count
}
return increment
}
let counter = makeCounter()
counter() // 1
counter() // 2
Возврат функции из функции — основа простых фабрик и замыканий без явного closure литерала.
@escaping и захват (кратко)
Если замыкание сохраняется и вызывается после возврата функции (асинхронно, в свойстве), параметр помечают @escaping. Иначе компилятор считает, что замыкание завершится до выхода из функции — это безопаснее для памяти.
При захвате self в классах избегайте циклов: [weak self] или [unowned self] в списке захвата. Подробнее — ООП в Swift и справочник.
Соглашения для своего API
| Ситуация | Рекомендация |
|---|---|
| Публичный метод с 3+ параметрами | Осмысленные внешние метки |
| «Оператор», математика | _ для всех или большинства |
| Побочный эффект над аргументом | inout + ясное имя |
| Асинхронный колбэк | @escaping, явный [weak self] в документации |
| SwiftUI / DSL | Trailing closure, @ViewBuilder (отдельно в фреймворках) |
Связанные материалы
См. также
Другие статьи этого же раздела в боковом меню (как на странице «О разделе»). История Swift - эволюция языка от замены Objective-C до современного инструмента разработки в экосистеме Apple. Экосистема приложений на Swift - инструменты, фреймворки и сценарии разработки в среде Apple. Swift — это современный, безопасный и производительный язык программирования общего назначения, разработанный компанией Apple. Набор советов, правил, принципов и обычаев в разработке на этом языке. Интерфейс класса служит контрактом между разработчиком класса и его пользователями. Он определяет, как взаимодействовать с объектом, не раскрывая механизмов работы. Простые приложения на Swift — CLI, Codable, файлы и сеть на Foundation. Основы Swift - базовый синтаксис, стандартные фреймворки и старт разработки в экосистеме Apple. Строки и Character, интерполяция, точка и вызов методов, запятая, опциональная точка с запятой, скобки и соглашения Swift для iOS и macOS. Ключевые слова Swift - справочник по основным конструкциям языка и их практическому применению. Набор функций, которые включены в стандартную библиотеку языка. Типизация, набор правил определения типа данных значений языка. Управляющие конструкции и циклы в Swift - условия, итерации и безопасное управление потоком выполнения.История языка Swift
Экосистема приложений на Swift
Что требуется знать перед началом изучения языка программирования Swift
Рекомендации по разработке на Swift
Объектно-ориентированное программирование в Swift
Простые приложения на Swift
Основы языка Swift
Синтаксис и пунктуация в Swift
Ключевые слова языка Swift
Встроенные функции и методы Swift
Типы данных и объявление переменных
Управляющие конструкции и циклы в Swift