Swift Language
funzioni
Ricerca…
Uso di base
Le funzioni possono essere dichiarate senza parametri o un valore di ritorno. L'unica informazione richiesta è un nome ( hello
in questo caso).
func hello()
{
print("Hello World")
}
Chiama una funzione senza parametri scrivendo il suo nome seguito da una coppia vuota di parentesi.
hello()
//output: "Hello World"
Funziona con i parametri
Le funzioni possono assumere parametri in modo che la loro funzionalità possa essere modificata. I parametri sono indicati come una lista separata da virgole con i loro tipi e nomi definiti.
func magicNumber(number1: Int)
{
print("\(number1) Is the magic number")
}
Nota: la sintassi \(number1)
è \(number1)
base della stringa e viene utilizzata per inserire il numero intero nella stringa.
Le funzioni con i parametri vengono chiamate specificando la funzione in base al nome e fornendo un valore di input del tipo utilizzato nella dichiarazione della funzione.
magicNumber(5)
//output: "5 Is the magic number
let example: Int = 10
magicNumber(example)
//output: "10 Is the magic number"
Potrebbe essere stato utilizzato qualsiasi valore di tipo Int.
func magicNumber(number1: Int, number2: Int)
{
print("\(number1 + number2) Is the magic number")
}
Quando una funzione utilizza più parametri, il nome del primo parametro non è richiesto per il primo ma è sui parametri successivi.
let ten: Int = 10
let five: Int = 5
magicNumber(ten,number2: five)
//output: "15 Is the magic number"
Utilizzare i nomi dei parametri esterni per rendere più leggibili le chiamate di funzione.
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)
L'impostazione del valore predefinito nella dichiarazione della funzione consente di chiamare la funzione senza fornire alcun valore di input.
func magicNumber(one number1: Int = 5, two number2: Int = 10)
{
print("\(number1 + number2) Is the magic number")
}
magicNumber()
//output: "15 Is the magic number"
Valori di ritorno
Le funzioni possono restituire valori specificando il tipo dopo l'elenco di parametri.
func findHypotenuse(a: Double, b: Double) -> Double
{
return sqrt((a * a) + (b * b))
}
let c = findHypotenuse(3, b: 5)
//c = 5.830951894845301
Le funzioni possono anche restituire più valori usando tuple.
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)
Errori di lancio
Se si desidera che una funzione sia in grado di generare errori, è necessario aggiungere la parola chiave throws
dopo le parentesi che contengono gli argomenti:
func errorThrower()throws -> String {}
Quando vuoi generare un errore, usa la parola chiave throw
:
func errorThrower()throws -> String {
if true {
return "True"
} else {
// Throwing an error
throw Error.error
}
}
Se si desidera chiamare una funzione che può generare un errore, è necessario utilizzare la parola chiave try
in un blocco do
:
do {
try errorThrower()
}
Per ulteriori informazioni sugli errori Swift: Errori
metodi
I metodi di istanza sono funzioni che appartengono a istanze di un tipo in Swift (una classe , una struttura , un'enumerazione o un protocollo ). I metodi Type vengono chiamati su un tipo stesso.
Metodi di istanza
I metodi di istanza sono definiti con una dichiarazione func
all'interno della definizione del tipo o in un'estensione .
class Counter {
var count = 0
func increment() {
count += 1
}
}
Il metodo di istanza increment()
viene chiamato su un'istanza della classe Counter
:
let counter = Counter() // create an instance of Counter class
counter.increment() // call the instance method on this instance
Digitare metodi
I metodi di tipo sono definiti con le parole chiave static func
. (Per le classi, la class func
definisce un metodo di tipo che può essere sovrascritto dalle sottoclassi).
class SomeClass {
class func someTypeMethod() {
// type method implementation goes here
}
}
SomeClass.someTypeMethod() // type method is called on the SomeClass type itself
Inout Parameters
Le funzioni possono modificare i parametri passati a loro se sono contrassegnati con la parola chiave inout
. Quando si passa un parametro inout
a una funzione, il chiamante deve aggiungere un &
alla variabile che si sta passando.
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".
Ciò consente di applicare la semantica di riferimento a tipi che normalmente hanno una semantica del valore.
Sintassi della chiusura finale
Quando l'ultimo parametro di una funzione è una chiusura
func loadData(id: String, completion:(result: String) -> ()) {
// ...
completion(result:"This is the result data")
}
la funzione può essere richiamata utilizzando la sintassi della chiusura del trailing
loadData("123") { result in
print(result)
}
Gli operatori sono funzioni
Operatori come +
, -
, ??
sono un tipo di funzione denominata utilizzando simboli anziché lettere. Sono invocati diversamente dalle funzioni:
- Prefisso:
- x
- Infix:
x + y
- Postfix:
x ++
Puoi leggere ulteriori informazioni sugli operatori di base e sugli operatori avanzati in Swift Programming Language.
Parametri Variadici
A volte, non è possibile elencare il numero di parametri di cui una funzione potrebbe avere bisogno. Considera una funzione sum
:
func sum(_ a: Int, _ b: Int) -> Int {
return a + b
}
Questo funziona bene per trovare la somma di due numeri, ma per trovare la somma di tre dovremmo scrivere un'altra funzione:
func sum(_ a: Int, _ b: Int, _ c: Int) -> Int {
return a + b + c
}
e uno con quattro parametri avrebbe bisogno di un altro, e così via. Swift rende possibile definire una funzione con un numero variabile di parametri usando una sequenza di tre periodi: ...
Per esempio,
func sum(_ numbers: Int...) -> Int {
return numbers.reduce(0, combine: +)
}
Si noti come il parametro numbers
, che è variadico, è fuso in una singola Array
di tipo [Int]
. Questo è vero in generale, i parametri variadici di tipo T...
sono accessibili come [T]
.
Questa funzione può ora essere chiamata così:
let a = sum(1, 2) // a == 3
let b = sum(3, 4, 5, 6, 7) // b == 25
Un parametro variadico in Swift non deve venire alla fine della lista dei parametri, ma può essercene uno solo in ogni firma di funzione.
A volte, è conveniente inserire una dimensione minima sul numero di parametri. Ad esempio, non ha senso prendere la sum
di nessun valore. Un modo semplice per far rispettare questo è mettere alcuni parametri richiesti non-variabili e quindi aggiungere il parametro variadic dopo. Per essere sicuri che la sum
possa essere chiamata solo con almeno due parametri, possiamo scrivere
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
pedici
Classi, strutture ed enumerazioni possono definire pedici, che sono scorciatoie per accedere agli elementi membri di una raccolta, un elenco o una sequenza.
Esempio
struct DaysOfWeek {
var days = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
subscript(index: Int) -> String {
get {
return days[index]
}
set {
days[index] = newValue
}
}
}
Uso degli abbonati
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])
Opzioni di iscrizione:
Gli indici di sottoscrizione possono prendere qualsiasi numero di parametri di input e questi parametri di input possono essere di qualsiasi tipo. Gli abbonati possono anche restituire qualsiasi tipo. Gli indici di sottoscrizione possono utilizzare parametri variabili e parametri variadici, ma non possono utilizzare parametri in-out o fornire valori di parametro predefiniti.
Esempio:
struct Food {
enum MealTime {
case Breakfast, Lunch, Dinner
}
var meals: [MealTime: String] = [:]
subscript (type: MealTime) -> String? {
get {
return meals[type]
}
set {
meals[type] = newValue
}
}
}
uso
var diet = Food()
diet[.Breakfast] = "Scrambled Eggs"
diet[.Lunch] = "Rice"
debugPrint("I had \(diet[.Breakfast]) for breakfast")
Funzioni con chiusure
L'uso di funzioni che accolgono ed eseguono chiusure può essere estremamente utile per inviare un blocco di codice da eseguire altrove. Possiamo iniziare consentendo alla nostra funzione di accettare una chiusura opzionale che (in questo caso) restituirà Void
.
func closedFunc(block: (()->Void)? = nil) {
print("Just beginning")
if let block = block {
block()
}
}
Ora che la nostra funzione è stata definita, chiamiamola e passa un codice:
closedFunc() { Void in
print("Over already")
}
Usando una chiusura finale con la nostra chiamata di funzione, possiamo passare il codice (in questo caso, print
) per essere eseguito in qualche punto all'interno della nostra funzione closedFunc()
.
Il registro dovrebbe stampare:
Appena iniziato
Già finito
Un caso d'uso più specifico di questo potrebbe includere l'esecuzione di codice tra due classi:
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?()
}
}
Il registro dovrebbe stampare:
1
2
Passare e restituire funzioni
La seguente funzione restituisce come risultato un'altra funzione che può essere successivamente assegnata a una variabile e chiamata:
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)
Tipi di funzioni
Ogni funzione ha un proprio tipo di funzione, costituito dai tipi di parametri e dal tipo di ritorno della funzione stessa. Ad esempio la seguente funzione:
func sum(x: Int, y: Int) -> (result: Int) { return x + y }
ha una funzione tipo di:
(Int, Int) -> (Int)
I tipi di funzione possono quindi essere utilizzati come tipi di parametri o come tipi di ritorno per le funzioni di nidificazione.