Поиск…


Основное использование

Функции могут быть объявлены без параметров или возвращаемого значения. Единственной необходимой информацией является имя ( 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)

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



Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow