Swift From Scratch een inleiding tot functies

Om iets gedaan te krijgen in Swift, moet je de ins en outs van functies leren. Functies zijn uitzonderlijk krachtig en flexibel in Swift. De basis is eenvoudig, vooral als je eerder met andere programmeertalen hebt gewerkt. Maar vanwege de flexibele syntaxis van Swift kunnen functies verwarrend zijn als u niet bekend bent met de basis. 

In dit artikel richten we ons eerst op de basis. Daarna gaan we verder met het verkennen van de complexere syntaxis en gebruiken we cases in het volgende artikel. Het is belangrijk dat u de basiselementen niet begrijpt, want ze zijn essentieel om te begrijpen waar de kracht van een functie vandaan komt. Laten we beginnen met het ontleden van de anatomie van een functie in Swift met een voorbeeld.

1. Leer door voorbeeld

Een functie is niets meer dan een codeblok dat kan worden uitgevoerd wanneer het nodig is. Laten we eens kijken naar een voorbeeld van de basisanatomie van een Swift-functie. Start Xcode op en maak een nieuwe speeltuin. Voeg de volgende functiedefinitie toe aan de speeltuin.

func printHelloWorld () print ("Hello World!")

Een functie begint met de func sleutelwoord en wordt gevolgd door de naam van de functie, printHelloWorld in ons voorbeeld. Zoals in veel andere talen, wordt de naam van de functie gevolgd door een paar haakjes die de parameters van de functie bevatten: de invoer voor de functie.

Het lichaam van de functie is gewikkeld in een paar accolades. De printHelloWorld () functie bevat één instructie waarmee de tekenreeks wordt afgedrukt Hallo Wereld! naar de standaarduitvoer. Dit is hoe een basisfunctie er in Swift uitziet. De syntaxis is eenvoudig, schoon en minimalistisch.

U kunt de functie oproepen door de naam van de functie in te typen, gevolgd door een paar haakjes.

printHelloWorld ()

2. Parameters

Laten we het bovenstaande voorbeeld wat complexer maken door parameters aan de functiedefinitie toe te voegen. Dit betekent eenvoudigweg dat we de functie voorzien van invoerwaarden die het in het lichaam van de functie kan gebruiken. In het volgende voorbeeld definiëren we de printMessage (message :) functie, die één parameter accepteert, bericht, van type Draad.

func printMessage (bericht: String) print (bericht)

Een functie kan meerdere parameters of invoerwaarden accepteren. De parameters zijn omwikkeld met de haakjes die de naam van de functie volgen. De naam van de parameter wordt gevolgd door een dubbele punt en het type van de parameter. Zoals u zich herinnert, lijkt dit sterk op het declareren van een variabele of constante. Het zegt gewoon dat het bericht parameter is van type Draad.

In plaats van een hardgecodeerde string te printen zoals in de printHelloWorld () functie, we drukken de bericht parameterwaarde. Dit maakt de functie flexibel en nuttiger.

Het aanroepen van de functie lijkt veel op wat we eerder zagen. Het enige verschil is dat we een argument doorgeven bij het aanroepen van de functie.

printMessage (bericht: "Hallo wereld!")

Merk op dat de voorwaarden parameters en argumenten worden vaak door elkaar gebruikt, maar er is een subtiel, semantisch verschil in Swift. In Swift zijn parameters de waarden die zijn opgegeven in de functiedefinitie, terwijl argumenten de waarden zijn die aan de functie worden doorgegeven wanneer deze wordt opgeroepen.

Meerdere parameters

Zoals ik eerder al zei, is de syntaxis van functies erg flexibel en het zou niet moeten verbazen dat het perfect mogelijk is om meerdere argumenten door te geven aan een functie. In het volgende voorbeeld maken we een variatie op de printMessage (message: keer :) functie waarmee we het bericht meerdere keren kunnen afdrukken.

func printMessage (bericht: String, times: Int) for i in 0 ... 

Hoewel de naam van de functie identiek is aan die van het origineel printMessage (message :) functie, het type van de functie is anders. 

Het is belangrijk dat u de vorige zin begrijpt. Lees het opnieuw.

Elke functie heeft een type, bestaande uit de parametertypen en het retourneringstype. We zullen retourtypen in een oogwenk onderzoeken. Functies kunnen dezelfde naam hebben zolang hun type anders is, zoals getoond door de vorige twee functiedefinities.

Het type van de eerste functie is (String) -> (), terwijl het type van de tweede functie is(String, Int) -> (). De naam van beide functies is hetzelfde. Maak je geen zorgen over de -> symbool. De betekenis ervan zal in enkele ogenblikken duidelijk worden wanneer we terugkeertypes bespreken.

De seconde printMessage (message: keer :) functie definieert twee parameters, bericht van type Draad en tijden van type Int. Deze definitie illustreert een van de functies die Swift heeft overgenomen van Objective-C, leesbare functie- en methode-namen. Terwijl de naam van de functie is printMessage, het is gemakkelijk te begrijpen wat de functie moet doen door de namen van de parameters van de functie te lezen.

In de seconde printMessage (message: keer :) functie maken we een voor-in lus om de bericht draad tijden tijden. We gebruiken de operator voor halfopen bereik, ... <, zoals we eerder in deze serie zagen.

Wanneer we beginnen met typen printMessage in de speeltuin geeft Xcode beide functies weer in het menu voor automatisch aanvullen. Dankzij het type van de functie, is het gemakkelijk om de functie te kiezen waarin we geïnteresseerd zijn printMessage (message: keer :) functie is zo simpel als:

printMessage (bericht: "Hello World", keer: 3)

Standaard waarden

Een van mijn favoriete functies is de mogelijkheid om standaardwaarden voor parameters te definiëren. Dit klinkt misschien gek als je uit een taal komt die deze functie al eeuwen heeft, maar dit is best wel leuk als je al vele jaren met C en Objective-C werkt.

Kort gezegd staat Swift ontwikkelaars toe om standaardwaarden te definiëren voor de parameters van een functie. Laten we een nieuwe functie definiëren die de huidige datum in een specifieke indeling afdrukt. Zorg ervoor dat je de volgende importverklaring boven aan je speeltuin toevoegt om het UIKit-framework te importeren.

importeer UIKit

Laten we eerst het definiëren PrintDate (datum: format :) functie zonder gebruik te maken van standaardwaarden voor een van de parameters.

func printDate (datum: Datum, formaat: String) let dateFormatter = DateFormatter () dateFormatter.dateFormat = format print (dateFormatter.string (from: date))

Als je niet bekend bent met het Foundation-raamwerk en je begrijpt niet wat er in het lichaam van de functie gebeurt, dan is dat prima. De focus van dit voorbeeld ligt niet op de implementatie van het formatteren van een datum. In PrintDate (datum: format :), we gebruiken de waarde van de formaat parameter om de waarde van te formatteren datum. Als we geen waarde doorgeven voor de formaat parameter, de compiler genereert een fout.

We kunnen dit verhelpen door een standaardwaarde te definiëren voor de tweede parameter van de functie, zoals weergegeven in de bijgewerkte functiedefinitie hieronder.

func printDate (datum: Date, format: String = "YY / MM / dd") let dateFormatter = DateFormatter () dateFormatter.dateFormat = format print (dateFormatter.string (from: date))

Het definiëren van een standaardwaarde is net zo eenvoudig als het opgeven van een waarde in de lijst met parameters in de definitie van de functie. Het resultaat is dat de compiler niet langer klaagt en de fout verdwijnt.

printDate (datum: Datum ())

Hoewel we een standaardwaarde hebben opgegeven voor de formaat parameter, we kunnen nog steeds een waarde doorgeven als we dat willen.

printDate (datum: Datum (), formaat: "dd / MM / YY")

Merk op dat Apple positioneringsparameters met een standaardwaarde aan het einde van de lijst met parameters aanbeveelt. Dit is zeker een goed idee en gebruikelijk in de meeste andere programmeertalen die optionele parameters ondersteunen.

3. Retourtype

De functies die we tot nu toe hebben gezien, geven ons niets terug als we ze oproepen. Laten we het maken PrintDate (datum: format :) functie nuttiger door de geformatteerde datum als een tekenreeks te retourneren, in plaats van de opgemaakte datum in de hoofdtekst van de functie af te drukken. Dit vereist twee wijzigingen, zoals u hieronder kunt zien.

func printDate (datum: Datum, formaat: String = "YY / MM / dd") -> String let dateFormatter = DateFormatter () dateFormatter.dateFormat = format return dateFormatter.string (from: date)

Het eerste dat we veranderen, is de definitie van de functie. Na de lijst met parameters, specificeren we het retourneringstype, Draad. Het retourtype wordt voorafgegaan door de -> symbool. Als je met CoffeeScript hebt gewerkt, ziet dit er bekend uit.

In plaats van de opgemaakte datum af te drukken met behulp van de drukken (_: separator: terminator :) functie gebruiken we de terugkeer sleutelwoord om de waarde uit de functie te retourneren. Dat is alles wat we moeten doen. Laten we het proberen.

let formattedDate = printDate (date: Date (), format: "dd / MM / YY") print (formattedDate)

We roepen het PrintDate (datum: format :) functie, sla de geretourneerde waarde op in de constante formattedDate, en druk de waarde af van formattedDate in de standaarduitvoer. Merk op dat de naam van de PrintDate (datum: format :) functie geeft niet langer weer wat het doet, dus u wilt het misschien wijzigen formatDate in plaats daarvan.

Geen retourtype

De andere functies die we in deze zelfstudie hebben gedefinieerd, hadden geen retourtype. Wanneer een functie geen retourneringstype heeft, is het niet nodig om de functie op te nemen -> symbool in de functiedefinitie.

Een paar alinea's eerder zei ik dat geen van de functies die we hadden gedefinieerd een waarde aan ons gaf. Dat is eigenlijk niet helemaal waar. Laat me de nitty-gritty details uitleggen met een experiment. Voeg de volgende regel toe aan je speeltuin en kijk wat er gebeurt.

Dit is interessant. Swift heeft geen probleem dat we de geretourneerde waarde van de printHelloWorld () functie in een constante, maar het waarschuwt ons wel dat het type geretourneerde waarde niet is wat we denken dat het is.

Wat gebeurt er hier? Elke functie in Swift retourneert een waarde, zelfs als we geen retentietype definiëren in de functiedefinitie. Wanneer een functie niet expliciet een retourneringstype specificeert, keert de functie impliciet terug leegte, wat gelijk is aan een lege tuple, of () in het kort. U kunt dit zien in het uitvoervenster van de speelplaats en dit wordt ook vermeld in de waarschuwing die de compiler uitvoert.

We kunnen de bovenstaande waarschuwing verwijderen door het type expliciet te verklaren waarde, een lege tuple. Ik ben het ermee eens dat het niet erg handig is om een ​​lege tuple in een constante op te slaan, maar het illustreert voor jou dat elke functie een retourwaarde heeft.

laat waarde: () = printHelloWorld ()

tuples

Een andere geweldige functie van Swift is de mogelijkheid om meerdere waarden uit een functie terug te geven door een tuple terug te zetten. Het volgende voorbeeld illustreert hoe dit werkt. Laat me herhalen dat het niet belangrijk is dat je begrijpt hoe het timeComponentsForDate (datum :) functie doet zijn werk. De focus ligt op de retourwaarde van de functie, een tuple met drie elementen.

func timeComponentsForDate (_ date: Date) -> (uur: Int, minuut: Int, second: Int) let dateComponents = Calendar.current.dateComponents ([. hour, .minute, .second], from: date) let hour = dateComponents.hour let minute = dateComponents.minute let second = dateComponents.second return (uur ?? 0, minuut ?? 0, seconde ?? 0)

De functie accepteert één argument, a Datum Bijvoorbeeld, en retourneert een tuple met drie gelabelde waarden. Het labelen van de waarden van de tuple is alleen voor het gemak; het is mogelijk om de labels weg te laten.

func timeComponentsForDate (_ datum: Datum) -> (Int, Int, Int) let dateComponents = Calendar.current.dateComponents ([. hour, .minute, .second], from: date) let hour = dateComponents.hour let minute = dateComponents.minute let second = dateComponents.second return (uur ?? 0, minuut ?? 0, seconde ?? 0)

Het volgende voorbeeld illustreert echter dat het labelen van de waarden van het tuple dat door de functie wordt geretourneerd erg handig is en uw code gemakkelijker te begrijpen maakt.

let timeComponents = timeComponentsForDate (Date ()) print (timeComponents.hour) print (timeComponents.minute) print (timeComponents.second)

Het is ook mogelijk om een ​​optionele waarde uit een functie te retourneren als er scenario's zijn waarbij de functie geen waarde heeft om terug te keren. Dit is net zo eenvoudig als het definiëren van het retourneertype van de functie als optioneel, zoals hieronder weergegeven.

func timeComponentsForDate (_ datum: Datum) -> (uur: Int, minuut: Int, seconde: Int)? let dateComponents = Calendar.current.dateComponents ([. hour, .minute, .second], from: date) guard let hour = dateComponents.hour else terug nul guard let minute = dateComponents.minute else terug nul bewaker laat second = dateComponents.second else return nil return (uur, minuut, seconde)

Conclusie

In deze zelfstudie hebben we de basisbeginselen van functies in Swift onderzocht. Het is belangrijk dat u de syntaxis van functies begrijpt, omdat we in het volgende artikel meer geavanceerde functies zullen verkennen die voortbouwen op wat we in deze zelfstudie hebben behandeld.

Ik raad u aan om het artikel opnieuw te lezen indien nodig en, nog belangrijker, een paar functies in een speeltuin te schrijven om bekend te raken met de syntaxis. De basis is gemakkelijk te begrijpen, maar je leert ze alleen door te oefenen.

Als je wilt leren hoe je Swift 3 kunt gebruiken om real-world apps te coderen, bekijk dan onze cursus Maak iOS-apps met Swift 3. Of je nu nieuw bent bij de ontwikkeling van iOS-apps of op zoek bent naar de overstap van Objective-C, deze Natuurlijk begin je met Swift voor app-ontwikkeling.