Szukaj…


Podstawowe użycie

Funkcje można zadeklarować bez parametrów lub wartości zwracanej. Jedyną wymaganą informacją jest nazwa (w tym przypadku hello ).

func hello()
{
    print("Hello World")
}

Wywołaj funkcję bez parametrów, wpisując jej nazwę, a następnie pustą parę nawiasów.

hello()
//output: "Hello World"

Funkcje z parametrami

Funkcje mogą przyjmować parametry, aby można było modyfikować ich funkcje. Parametry podano jako listę oddzieloną przecinkami, ze zdefiniowanymi ich typami i nazwami.

func magicNumber(number1: Int)
{
    print("\(number1) Is the magic number")
}

Uwaga: Składnia \(number1) jest podstawową interpolacją ciągu znaków i służy do wstawiania liczby całkowitej do ciągu.

Funkcje z parametrami są wywoływane przez określenie funkcji według nazwy i podanie wartości wejściowej typu użytego w deklaracji funkcji.

magicNumber(5)
//output: "5 Is the magic number
let example: Int = 10
magicNumber(example)
//output: "10 Is the magic number"

Można użyć dowolnej wartości typu Int.

func magicNumber(number1: Int, number2: Int)
{
    print("\(number1 + number2) Is the magic number")
}

Gdy funkcja używa wielu parametrów, nazwa pierwszego parametru nie jest wymagana dla pierwszego, ale dotyczy kolejnych parametrów.

let ten: Int = 10
let five: Int = 5
magicNumber(ten,number2: five)
//output: "15 Is the magic number"

Użyj nazw parametrów zewnętrznych, aby wywołania funkcji były bardziej czytelne.

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)

Ustawienie wartości domyślnej w deklaracji funkcji umożliwia wywołanie funkcji bez podawania wartości wejściowych.

func magicNumber(one number1: Int = 5, two number2: Int = 10)
{
    print("\(number1 + number2) Is the magic number")
}

magicNumber()
//output: "15 Is the magic number"

Zwracane wartości

Funkcje mogą zwracać wartości, określając typ po liście parametrów.

func findHypotenuse(a: Double, b: Double) -> Double
{
    return sqrt((a * a) + (b * b))
}

let c = findHypotenuse(3, b: 5)
//c = 5.830951894845301

Funkcje mogą również zwracać wiele wartości za pomocą krotek.

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)

Błędy rzucania

Jeśli chcesz, aby funkcja mogła zgłaszać błędy, musisz dodać słowo kluczowe throws po nawiasach zawierających argumenty:

func errorThrower()throws -> String {}

Jeśli chcesz zgłosić błąd, użyj słowa kluczowego throw :

func errorThrower()throws -> String {
  if true {
    return "True"
  } else {
    // Throwing an error
    throw Error.error 
  }
}

Jeśli chcesz wywołać funkcję, która może wygenerować błąd, trzeba użyć try słowa kluczowego w do bloku:

do {
  try errorThrower()
}

Więcej informacji o błędach Swift: Błędy

Metody

Metody instancji to funkcje należące do instancji typu w Swift ( klasa , struktura , wyliczenie lub protokół ). Metody typu są wywoływane na samym typie.

Metody instancji

Metody instancji są definiowane za pomocą deklaracji func w definicji typu lub w rozszerzeniu .

class Counter {
    var count = 0
    func increment() {
        count += 1
    }
}

Metoda instancji increment() jest wywoływana w instancji klasy Counter :

let counter = Counter()  // create an instance of Counter class   
counter.increment()      // call the instance method on this instance

Metody typu

Metody typu są definiowane za pomocą static func słów kluczowych static func . (W przypadku klas class func definiuje metodę typu, którą można zastąpić podklasami).

class SomeClass {
    class func someTypeMethod() {
        // type method implementation goes here
    }
}
SomeClass.someTypeMethod()  // type method is called on the SomeClass type itself

Parametry wejściowe

Funkcje mogą modyfikować przekazane im parametry, jeśli są oznaczone słowem kluczowym inout . Przy przekazywaniu parametru inout do funkcji wywołujący musi dodać znak & do przekazywanej zmiennej.

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".

Umożliwia to zastosowanie semantyki odniesienia do typów, które normalnie miałyby semantykę wartości.

Składnia końcowego zamknięcia

Gdy ostatnim parametrem funkcji jest zamknięcie

func loadData(id: String, completion:(result: String) -> ()) {
    // ...
    completion(result:"This is the result data")
}

funkcję można wywołać za pomocą składni końcowego zamykania

loadData("123") { result in
    print(result)
}

Operatory to funkcje

Operatory takie jak + , - , ?? są rodzajem funkcji nazwanych za pomocą symboli zamiast liter. Są wywoływane inaczej niż funkcje:

  • Prefiks: - x
  • Infix: x + y
  • Postfiks: x ++

Możesz przeczytać więcej o podstawowych operatorach i operatorach zaawansowanych w Swift Programming Language.

Parametry Variadic

Czasami nie jest możliwe podanie liczby parametrów, których może potrzebować funkcja. Rozważ funkcję sum :

func sum(_ a: Int, _ b: Int) -> Int {
    return a + b
}

Działa to dobrze, aby znaleźć sumę dwóch liczb, ale aby znaleźć sumę trzech, musielibyśmy napisać inną funkcję:

func sum(_ a: Int, _ b: Int, _ c: Int) -> Int {
    return a + b + c
}

i jeden z czterema parametrami potrzebowałby innego i tak dalej. Swift umożliwia zdefiniowanie funkcji o zmiennej liczbie parametrów za pomocą sekwencji trzech okresów: ... Na przykład,

func sum(_ numbers: Int...) -> Int {
    return numbers.reduce(0, combine: +)
}

Zwróć uwagę, w jaki sposób parametr numbers , który jest variadic, zlewa się w jedną Array typu [Int] . Zasadniczo jest to prawda, różne parametry typu T... są dostępne jako [T] .

Tę funkcję można teraz wywołać w następujący sposób:

let a = sum(1, 2) // a == 3
let b = sum(3, 4, 5, 6, 7) // b == 25

Parametr variadic w Swift nie musi znajdować się na końcu listy parametrów, ale może być tylko jeden w podpisie każdej funkcji.

Czasami wygodnie jest ustawić minimalny rozmiar liczby parametrów. Na przykład nie ma sensu przyjmowanie sum żadnych wartości. Łatwym sposobem na wymuszenie tego jest umieszczenie niektórych nie-wariadycznych wymaganych parametrów, a następnie dodanie parametru variadic po. Aby upewnić się, że sum można wywołać tylko z co najmniej dwoma parametrami, możemy napisać

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

Indeksy dolne

Klasy, struktury i wyliczenia mogą definiować indeksy dolne, które są skrótami do uzyskiwania dostępu do elementów składowych kolekcji, listy lub sekwencji.

Przykład

struct DaysOfWeek {
  
  var days = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
  
  subscript(index: Int) -> String {
    get {
      return days[index]
    }
    set {
      days[index] = newValue
    }
  }
}

Wykorzystanie indeksu dolnego

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])

Opcje indeksów dolnych:

Indeksy dolne mogą przyjmować dowolną liczbę parametrów wejściowych, a te parametry wejściowe mogą być dowolnego typu. Indeksy dolne mogą również zwracać dowolny typ. Indeksy dolne mogą wykorzystywać parametry zmienne i parametry wariadyczne, ale nie mogą używać parametrów wejściowych ani domyślnych wartości parametrów.

Przykład:

struct Food {
  
  enum MealTime {
    case Breakfast, Lunch, Dinner
  }
  
  var meals: [MealTime: String] = [:]
  
  subscript (type: MealTime) -> String? {
    get {
      return meals[type]
    }
    set {
      meals[type] = newValue
    }
  }
}

Stosowanie

var diet = Food()
diet[.Breakfast] = "Scrambled Eggs"
diet[.Lunch] = "Rice"

debugPrint("I had \(diet[.Breakfast]) for breakfast")

Funkcje z zamknięciami

Korzystanie z funkcji, które przyjmują i wykonują zamknięcia, może być niezwykle przydatne do wysyłania bloku kodu do wykonania w innym miejscu. Możemy zacząć od zezwolenia naszej funkcji na opcjonalne zamknięcie, które (w tym przypadku) zwróci Void .

func closedFunc(block: (()->Void)? = nil) {
    print("Just beginning")

    if let block = block {
        block()
    }
}

Teraz, gdy nasza funkcja została zdefiniowana, wywołajmy ją i przekażmy kod:

closedFunc() { Void in
    print("Over already")
}

Używając końcowego zamknięcia w naszym wywołaniu funkcji, możemy przekazać kod (w tym przypadku print ), który zostanie wykonany w pewnym momencie w ramach naszej funkcji closedFunc() .

Dziennik powinien zostać wydrukowany:

Dopiero zaczynam

Już skończone


Bardziej konkretny przypadek użycia tego może obejmować wykonanie kodu między dwiema klasami:

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?()
    }
}

Dziennik powinien zostać wydrukowany:

1

2)

Przekazywanie i zwracanie funkcji

Następująca funkcja zwraca inną funkcję w wyniku, którą można później przypisać do zmiennej i wywołać:

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)

Rodzaje funkcji

Każda funkcja ma swój własny typ funkcji, złożony z typów parametrów i typu zwracanego przez samą funkcję. Na przykład następująca funkcja:

func sum(x: Int, y: Int) -> (result: Int) { return x + y }

ma typ funkcji:

(Int, Int) -> (Int)

Typy funkcji mogą być zatem używane jako typy parametrów lub jako typy zwrotne dla funkcji zagnieżdżania.



Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow