Функции в Swift

Функция в Swift имеет тип, описывающий тип параметров функции и тип возвращаемого значения. Функция может быть параметром другой функции либо ее результирующим значением, они также могут вкладываться друг в друга. При объявлении функции можно задать одно или несколько именованных типизированных значений, которые будут ее входными данными (или параметрами), а также тип значения, которое функция будет передавать в качестве результата (или возвращаемый тип).



func sum(param1: Double, param2: Double) -> Double {
    return param1 + param2
}


Функции могут не иметь входных параметров или не иметь возвращаемого типа(в ее объявлении будет отсутствовать результирующая стрелка (->) и возвращаемый тип). Выходное значение функции может быть игнорировано:



func sum(param1: Double, param2: Double){
    return param1 + param2
}


Чтобы возвращать из функции несколько значений в виде составного параметра, нужно объявить функцию типа кортеж:



func minMax(array: [Int]) -> (min: Int, max: Int) {
    var currentMin = array[0]
    var currentMax = array[0]

    for value in array[1..<array.count] {
    	if value < currentMin {
    		currentMin = value
		} else if value > currentMax {
    		currentMax = value
    	}
    }

    return (currentMin, currentMax)
}


Если возвращаемый из функции кортеж может иметь "пустое значение", то его следует объявить как кортеж-опционал, т. е. кортеж, который может равняться nil. Чтобы сделать возвращаемый кортеж опционалом, нужно поставить вопросительный знак после закрывающей скобки.



Кортеж-опционал вида (Int, Int)? это не то же самое, что кортеж, содержащий опционалы: (Int?, Int?). Кортеж-опционал сам является опционалом, но не обязан состоять из опциональных значений.


Чтобы при вызове функции можно было присвоить имена ее параметрам, объявляются для них внешние имена в дополнение к локальным. Внешнее имя параметра записывается перед соответствующим локальным через пробел:



//объявление функции
func someFunction(externalParameterName localParameterName: Int) {
// тело функции, в котором можно использовать localParameterName
}

//вызов такой функции
someFunction(externalParameterName: 6)


Если необходимо задать внешнее имя для параметра функции, у которого уже есть подходящее локальное имя, то дублировать это имя не требуется. Вместо этого можно написать имя один раз и поставить перед ним решетку (#):



//объявление функции
func someFunction(#myParameterName: Int) {
// тело функции, в котором можно использовать localParameterName
}

//вызов такой функции
someFunction(myParameterName: 6)


При объявлении функции любому из ее параметров можно присвоить значение по умолчанию. Если у параметра есть значение по умолчанию, то при вызове функции этот параметр можно опустить:



//объявление функции
func someFunction(myParameterName: String = "myValue") {
// тело функции, в котором можно использовать localParameterName
}

//вызов такой функции
someFunction(){
	//myParameterName будет иметь значение "myValue"
}


Для удобства язык Swift автоматически присваивает внешние имена всем параметрам, имеющим значения по умолчанию. Автоматически созданное внешнее имя совпадает с локальным, как если бы перед локальным именем стояло (#).


Вариативным называет параметр, который может иметь сразу несколько значений или не иметь ни одного. С помощью вариативного параметра можно передать в функцию произвольное число входных значений. Чтобы объявить параметр как вариативный, нужно поставить три точки (...) после его типа:



func someFunction(numbers: Double...) -> Double {
	/ ...

	for number in numbers {
	
	}

	// ...
}

someFunction(1, 2, 3, 4, 5)



У функции может быть только один вариативный параметр, который всегда должен стоять последним в списке параметров, чтобы при вызове функции, имеющей несколько параметров, не возникало двусмысленности.


По умолчанию параметры функции являются константами, поэтому попытка изменить значение параметра функции из тела этой же функции приведет к ошибке времени компиляции! Чтобы объявить параметр как переменный, нужно перед его именем поставить ключевое слово var. Изменения переменных параметров не сохраняются после завершения работы функции и не видны за ее пределами. Переменные параметры существуют только во время работы функции.


Чтобы после завершения работы функции ее измененные параметры сохранялись, нужно объявить их не как переменные, а как сквозные параметры. Для создания сквозного параметра нужно поставить ключевое слово inout перед объявлением параметра. Сквозной параметр передает значение в функцию, которое затем изменяется в ней и возвращается из функции, заменяя исходное значение. Аргументом для сквозного параметра может быть только переменная. Непосредственно перед именем переменной ставится амперсанд (&), обозначающий, что аргумент, переданный как входной параметр, можно изменять в теле функции.


Сквозные параметры не могут иметь значения по умолчанию и не могут быть вариативными параметрами с ключевым словом inout. Если параметр объявлен как inout, для него уже нельзя использовать var или let. Сквозные параметры – это альтернативный способ передачи изменений, сделанных внутри функции, за пределы тела этой функции.


Помимо глобальных можно объявлять и функции, находящиеся внутри других функций, или же вложенные. Вложенные функции по умолчанию недоступны извне, а вызываются и используются только родительской функцией. Родительская функция может также возвращать одну из вложенных, чтобы вложенную функцию можно было использовать за ее пределами.