Funcțiile iți oferă posibilitatea de a definii bucăți de cod refolosibile care execută funcționalități specifice. De obicei funcțiile sunt capabile să accepte unele valori pentru a modifica modul în care rulează, dar acest lucru nu este necesar.
Să începem cu o funcție simplă:
func favoriteAlbum() {
print("My favorite is Fearless")
}
Dacă pui acest cod în playground-ul tău, nimic nu va fi afișat. Și da, este corect. Motivul pentru care nimic nu este afișat este că am pus mesajul "My favorite is Fearless" într-o funcție numită favoriteAlbum()
, și acel cod nu va rula până nu îi vom cere Swift-ului să ruleze funcția favoriteAlbum()
. Pentru a face asta, adaugă această linie de cod:
favoriteAlbum()
Aceasta va rula funcția (sau o va "apela"), prin urmare acum vei vedea afișat "My favorite is Fearless".
După cum poți vedea, o funcție este definită prin a scrie func
, apoi numele funcției tale, apoi deschizi și închizi parantezele, apoi codul propriu-zis scris în interiorul parantezelor pătrate. Funcția poate fi mai apoi apelată folosind numele ei urmat de paranteze închise și deschise.
Bineînțeles, acesta este un exemplu prostesc – acea funcție face același lucru orice ar fi, de aceea nu are niciun motiv de a exista. Dar dacă am vrea să afișăm un album diferit de fiecare dată? În acest caz, am putea să îi spunem Swift-ului că vrem ca funcția noastră să accepte o valoare când este chemată, iar apoi am putea folosi acea valoare în interiorul ei.
Hai să facem asta acum:
func favoriteAlbum(name: String) {
print("My favorite is \(name)")
}
Astfel îi spunem lui Swift că vrem ca funcția să accepte o valoare (numită "parametru"), numit "name", care trebuie să fie de tipul string. Apoi folosim interpolarea string-urilor pentru a scrie numele albumului favorit direct în mesajul nostru. Pentru a apela funcția acum, ai scrie asta:
favoriteAlbum(name: "Fearless")
Încă te-ai putea întreba care este rostul, dat fiind faptul că este doar o linie de cod. Ei bine, imaginează-ți că am folosit funcția în 20 de locuri diferite într-o aplicație mare, apoi designer-ul șef vine și îți spune să modifici mesajul în "I love Fearless so much – it's my favorite!". Chiar ai vrea să cauți cele 20 de instanțe în codul tău? Probabil că nu. Cu o funcție îl modifici odată, și totul este actualizat.
Poți scrie funcțiile astfel încât acestea să accepte câți parametru vrei tu, așa că hai să îi mai adăugăm un parametru name si altul year:
func printAlbumRelease(name: String, year: Int) {
print("\(name) was released in \(year)")
}
printAlbumRelease(name: "Fearless", year: 2008)
printAlbumRelease(name: "Speak Now", year: 2010)
printAlbumRelease(name: "Red", year: 2012)
Numele acestor parametrii sunt importante, și fac parte, de fapt din numele funcției. Uneori vei vedea mai multe funcții cu același nume, de exemplu handle()
, dar cu parametrii care au nume diferite pentru a putea fi diferențiate.
Uneori vrei ca parametrii să aibă un nume când o funcție este apelată, dar alt nume în interiorul funcției. Asta înseamnă că atunci când apelezi funcția aceasta folosește un limbaj aproape natural, dar în interiorul funcției parametrii au nume logice. Această tehnică este folosită foarte frecvent în Swift, așa că merită să o înțelegem acum.
Pentru a o demonstra, haide să scriem o funcție care afișează numărul de litere dintr-un șir de caractere. Acesta este accesibil folosind proprietatea count
a șirurilor de caractere, așa că am putea scrie în felul următor:
func countLettersInString(string: String) {
print("The string \(string) has \(string.count) letters.")
}
Având acea funcție, am putea să o apelăm așa:
countLettersInString(string: "Hello")
Chiar dacă funcționează, are puțin prea multe cuvinte. În plus, nu este ceva ce ai spune cu voce tare: "count letters in string string hello".
Swift îți acordă posibilitatea de a specifica un nume pentru parametru atunci când este apelat, și alt nume în interiorul metodei. Pentru a face asta, scrie numele parametrului de două ori – odată pentru cel extern, odată pentru cel intern.
De exemplu, am putea numi parametrul myString
când este apelat, și str
în interiorul metodei, așa:
func countLettersInString(myString str: String) {
print("The string \(str) has \(str.count) letters.")
}
countLettersInString(myString: "Hello")
Poți de asemenea să scrii _
ca și nume de parametru extern, iar acest lucru îi va spune lui Swift că nu trebuie să aibă niciun nume extern. De exemplu:
func countLettersInString(_ str: String) {
print("The string \(str) has \(str.count) letters.")
}
countLettersInString("Hello")
După cum poți vedea, asta face ca linia de cod să se citească precum o propoziție în engleză: “count letters in string hello”.
Pe când sunt multe cazuri în care folosirea _
este alegerea corectă, programatorii Swift preferă în general să denumească toți parametrii. Și gandește-te: de ce avem nevoie de cuvântul "String" în funție – pentru ce altceva am vrea să numărăm literele?
Deci, în general vei vedea nume de parametrii externi precum “in”, “for”, și “with”, iar nume de parametrii interni cu mai mult înțeles. Deci, modul "Swift" de a defini o funcție este acesta:
func countLetters(in string: String) {
print("The string \(string) has \(string.count) letters.")
}
Ceea ce înseamnă că vei apela funcția cu parametrul "in", care ar fi lipsit de înțeles în interiorul funcției. Totuși, în interiorul funcției același parametru este numit "string", ceea ce îl face mai folositor. Deci, funcția poate fi apelată astfel:
countLetters(in: "Hello")
Și acesta este cod cu adevărat Swift: “count letters in hello” se citește ca în limba engleză vorbită, dar codul este clar si concis.
Funcțiile Swift pot returna o valoare prin a scrie ->
apoi un tip de date după lista de parametrii. Odată ce faci asta, Swift se va asigura că funcția ta va returna o valoare indiferent de situație, deci tu faci din nou o promisiune despre ceea ce face codul tău.
Ca și exemplu, să scriem o funcție care returnează true dacă unul dintre albume aparține lui Taylor Swift, sau false în caz contrar. Va trebui să accepte un parametru (numele albumului) și va returna un Boolean. Acesta este codul:
func albumIsTaylor(name: String) -> Bool {
if name == "Taylor Swift" { return true }
if name == "Fearless" { return true }
if name == "Speak Now" { return true }
if name == "Red" { return true }
if name == "1989" { return true }
return false
}
Dacă vrei să îți testezi noile cunoștințe switch/case
, în această funcție va funcționa bine.
Acum poți să o apelezi furnizând numele albumului și poți acționa pe baza rezultatului:
if albumIsTaylor(name: "Red") {
print("That's one of hers!")
} else {
print("Who made that?!")
}
if albumIsTaylor(name: "Blue") {
print("That's one of hers!")
} else {
print("Who made that?!")
}
SPONSORED Join a FREE crash course for mid/senior iOS devs who want to achieve an expert level of technical and practical skills – it’s the fast track to being a complete senior developer! Hurry up because it'll be available only until October 1st.
Sponsor Hacking with Swift and reach the world's largest Swift community!
Link copied to your pasteboard.