Swift Language
функции
Поиск…
Основное использование
Функции могут быть объявлены без параметров или возвращаемого значения. Единственной необходимой информацией является имя ( hello
в этом случае).
func hello()
{
print("Hello World")
}
Вызовите функцию без параметров, записав ее имя, а затем пустую пару скобок.
hello()
//output: "Hello World"
Функции с параметрами
Функции могут принимать параметры, чтобы их функциональность могла быть изменена. Параметры задаются как список, разделенный запятыми, с указанием их типов и имен.
func magicNumber(number1: Int)
{
print("\(number1) Is the magic number")
}
Примечание. Синтаксис \(number1)
является базовой интерполяцией строк и используется для вставки целого в String.
Функции с параметрами вызываются путем указания функции по имени и подачи входного значения типа, используемого в объявлении функции.
magicNumber(5)
//output: "5 Is the magic number
let example: Int = 10
magicNumber(example)
//output: "10 Is the magic number"
Любое значение типа Int могло быть использовано.
func magicNumber(number1: Int, number2: Int)
{
print("\(number1 + number2) Is the magic number")
}
Когда функция использует несколько параметров, имя первого параметра не требуется для первого, а имеет следующие параметры.
let ten: Int = 10
let five: Int = 5
magicNumber(ten,number2: five)
//output: "15 Is the magic number"
Используйте внешние имена параметров, чтобы сделать вызовы функций более читабельными.
func magicNumber(one number1: Int, two number2: Int)
{
print("\(number1 + number2) Is the magic number")
}
let ten: Int = 10
let five: Int = 5
magicNumber(one: ten, two: five)
Установка значения по умолчанию в объявлении функции позволяет вызывать функцию без ввода каких-либо входных значений.
func magicNumber(one number1: Int = 5, two number2: Int = 10)
{
print("\(number1 + number2) Is the magic number")
}
magicNumber()
//output: "15 Is the magic number"
Возвращаемые значения
Функции могут возвращать значения, задавая тип после списка параметров.
func findHypotenuse(a: Double, b: Double) -> Double
{
return sqrt((a * a) + (b * b))
}
let c = findHypotenuse(3, b: 5)
//c = 5.830951894845301
Функции также могут возвращать несколько значений с помощью кортежей.
func maths(number: Int) -> (times2: Int, times3: Int)
{
let two = number * 2
let three = number * 3
return (two, three)
}
let resultTuple = maths(5)
//resultTuple = (10, 15)
Ошибки
Если вы хотите, чтобы функция , чтобы быть в состоянии бросить ошибки, вам нужно добавить throws
ключевого слова после скобок , которые содержат аргументы:
func errorThrower()throws -> String {}
Когда вы хотите выбросить ошибку, используйте ключевое слово throw
:
func errorThrower()throws -> String {
if true {
return "True"
} else {
// Throwing an error
throw Error.error
}
}
Если вы хотите вызвать функцию, которая может вызвать ошибку, вам нужно использовать ключевое слово try
в блоке do
:
do {
try errorThrower()
}
Подробнее о ошибках Swift: Ошибки
методы
Методы экземпляра - это функции, относящиеся к экземплярам типа в Swift ( класс , структура , перечисление или протокол ). Методы типа вызываются по самому типу.
Методы экземпляра
Методы экземпляров определяются с объявлением func
внутри определения типа или в расширении .
class Counter {
var count = 0
func increment() {
count += 1
}
}
Метод экземпляра increment()
вызывается в экземпляре класса Counter
:
let counter = Counter() // create an instance of Counter class
counter.increment() // call the instance method on this instance
Методы типа
Методы типов определяются со static func
ключевыми словами static func
. (Для классов class func
определяет метод типа, который может быть переопределен подклассами.)
class SomeClass {
class func someTypeMethod() {
// type method implementation goes here
}
}
SomeClass.someTypeMethod() // type method is called on the SomeClass type itself
Параметры Inout
Функции могут изменять переданные им параметры, если они отмечены ключевым словом inout
. При передаче параметра inout
функции, вызывающий должен добавить &
к передаваемой переменной.
func updateFruit(fruit: inout Int) {
fruit -= 1
}
var apples = 30 // Prints "There's 30 apples"
print("There's \(apples) apples")
updateFruit(fruit: &apples)
print("There's now \(apples) apples") // Prints "There's 29 apples".
Это позволяет применять ссылочную семантику к типам, которые обычно имеют семантику значений.
Синтаксис закрытия трейлинга
Когда последний параметр функции является замыканием
func loadData(id: String, completion:(result: String) -> ()) {
// ...
completion(result:"This is the result data")
}
функция может быть вызвана с помощью синтаксиса Trailing Closure
loadData("123") { result in
print(result)
}
Операторы - это функции
Операторы, такие как +
, -
, ??
являются своего рода функцией с использованием символов, а не букв. Они вызываются иначе, чем функции:
- Префикс:
- x
- Infix:
x + y
- Postfix:
x ++
Вы можете больше узнать об основных операторах и расширенных операторах на языке Swift Programming.
Вариадические параметры
Иногда невозможно указать количество параметров, которые могут понадобиться функции. Рассмотрим функцию sum
:
func sum(_ a: Int, _ b: Int) -> Int {
return a + b
}
Это отлично подходит для нахождения суммы двух чисел, но для нахождения суммы трех мы должны были бы написать другую функцию:
func sum(_ a: Int, _ b: Int, _ c: Int) -> Int {
return a + b + c
}
и один с четырьмя параметрами понадобится другой, и так далее. Swift позволяет определить функцию с переменным числом параметров, используя последовательность из трех периодов: ...
Например,
func sum(_ numbers: Int...) -> Int {
return numbers.reduce(0, combine: +)
}
Обратите внимание, что параметр numbers
, который является переменным, объединяется в один Array
типа [Int]
. Это в общем случае, вариационные параметры типа T...
доступны как [T]
.
Теперь эту функцию можно вызвать так:
let a = sum(1, 2) // a == 3
let b = sum(3, 4, 5, 6, 7) // b == 25
Параметр Variable в Swift не должен появляться в конце списка параметров, но в каждой сигнатуре функции может быть только один.
Иногда удобно указывать минимальный размер числа параметров. Например, на самом деле нет смысла брать sum
значений. Простой способ обеспечить это - это добавить некоторые невариантные требуемые параметры, а затем добавить переменный параметр после. Чтобы убедиться, что sum
может быть вызвана хотя бы двумя параметрами, мы можем написать
func sum(_ n1: Int, _ n2: Int, _ numbers: Int...) -> Int {
return numbers.reduce(n1 + n2, combine: +)
}
sum(1, 2) // ok
sum(3, 4, 5, 6, 7) // ok
sum(1) // not ok
sum() // not ok
Нижние индексы
Классы, структуры и перечисления могут определять индексы, которые являются ярлыками для доступа к элементам-членам коллекции, списка или последовательности.
пример
struct DaysOfWeek {
var days = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
subscript(index: Int) -> String {
get {
return days[index]
}
set {
days[index] = newValue
}
}
}
Использование подзаголовков
var week = DaysOfWeek()
//you access an element of an array at index by array[index].
debugPrint(week[1])
debugPrint(week[0])
week[0] = "Sunday"
debugPrint(week[0])
Параметры подписок:
Подписчики могут принимать любое количество входных параметров, и эти входные параметры могут быть любого типа. Подписчики могут также возвращать любой тип. В подзаголовках могут использоваться переменные параметры и переменные параметры, но они не могут использовать параметры вывода или задавать значения параметров по умолчанию.
Пример:
struct Food {
enum MealTime {
case Breakfast, Lunch, Dinner
}
var meals: [MealTime: String] = [:]
subscript (type: MealTime) -> String? {
get {
return meals[type]
}
set {
meals[type] = newValue
}
}
}
использование
var diet = Food()
diet[.Breakfast] = "Scrambled Eggs"
diet[.Lunch] = "Rice"
debugPrint("I had \(diet[.Breakfast]) for breakfast")
Функции с закрытием
Использование функций, выполняющих и выполняющих закрытие, может быть чрезвычайно полезно для отправки блока кода, который будет выполнен в другом месте. Мы можем начать с того, что позволили нашей функции взять необязательное закрытие, которое (в этом случае) вернет Void
.
func closedFunc(block: (()->Void)? = nil) {
print("Just beginning")
if let block = block {
block()
}
}
Теперь, когда наша функция определена, назовем ее и передадим в код:
closedFunc() { Void in
print("Over already")
}
Используя трейлинг-закрытие с помощью нашего вызова функции, мы можем передать код (в данном случае, print
), который будет выполнен в какой-то момент в нашей функции closedFunc()
.
Журнал должен печатать:
Только начало
Уже
Более конкретный вариант использования этого может включать выполнение кода между двумя классами:
class ViewController: UIViewController {
override func viewDidLoad() {
let _ = A.init(){Void in self.action(2)}
}
func action(i: Int) {
print(i)
}
}
class A: NSObject {
var closure : ()?
init(closure: (()->Void)? = nil) {
// Notice how this is executed before the closure
print("1")
// Make sure closure isn't nil
self.closure = closure?()
}
}
Журнал должен печатать:
1
2
Функции передачи и возврата
Следующая функция возвращает в качестве результата другую функцию, которая впоследствии может быть назначена переменной и называется:
func jediTrainer () -> ((String, Int) -> String) {
func train(name: String, times: Int) -> (String) {
return "\(name) has been trained in the Force \(times) times"
}
return train
}
let train = jediTrainer()
train("Obi Wan", 3)
Типы функций
Каждая функция имеет свой собственный тип функции, состоящий из типов параметров и типа возврата самой функции. Например, следующая функция:
func sum(x: Int, y: Int) -> (result: Int) { return x + y }
имеет тип функции:
(Int, Int) -> (Int)
Таким образом, типы функций могут использоваться как типы параметров или типы возврата для функций вложенности.