Swift fra Scratch: Funksjonsparametere, typer og Nesting

Swift fra Scratch: Funksjonsparametere, typer og Nesting
23
Del
Del
Share < .no> Dette Cyber ​​mandag Envato Tuts + kurs vil bli redusert til bare $ 3. Ikke gå glipp av
Dette innlegget er en del av en serie som heter Swift fra Scratch.Swift fra Scratch:. En introduksjon til FunctionsSwift fra Scratch: Nedleggelser

I forrige artikkel, vi utforsket det grunnleggende funksjoner i Swift. Funksjoner, men har mye mer å tilby. I denne artikkelen vil vi fortsette vår utforskning av funksjoner og ser inn i funksjonsparametre, fuglefjell, og typer.

1. Lokal & Eksterne parameternavn

Lokale parameternavn

La oss se ett av eksemplene i den forrige artikkelen. Den printMessage funksjonen definerer en parameter, melding
func printMessage. (Message: String) {println (melding)}

Selv om vi gir parameter et navn, melding, vi bruker ikke navnet når vi kaller funksjon. Vi passerer i verdien for meldingen parameter.
PrintMessage ("Hei, verden!")

Navnet vi definerer i funksjonen definisjon er en lokal parameternavn. Verdien av parameteren kan bare bli referert til av dette navn i kroppen av funksjonen. Funksjonsparametre, men er litt mer fleksible enn. La meg forklare hva jeg mener med det.

Objective-C er kjent for sine lange metodenavn. Selv om dette kan se klumpete og uelegant til utenforstående, gjør det metoder lett å forstå, og hvis valgt godt, veldig beskrivende. Hvis du tror du mistet denne fordelen når du bytter til Swift, så du er i for en overraskelse.

Eksterne parameternavn

Når en funksjon godtar flere parametre, er det ikke alltid opplagt hvilke argument tilsvarer som parameter. Ta en titt på følgende eksempel for å bedre forstå problemet
func makt (a: Int, b: Int.) - ≫ Int {var resultat = en for _ i en .. < b {resultat = resultat * a} retur resultat}

Strøm funksjon som øker verdien av en av eksponenten b. Begge parametere er av type Int. Mens de fleste vil intuitivt passere basisverdien som første argument og eksponenten som det andre argumentet, dette er ikke klart fra funksjonens type, navn eller signatur. Som vi har sett i den forrige artikkelen, påkalle funksjonen er grei.
Kraft (2, 3)

For å unngå forvirring, kan vi gi parametrene for en funksjon eksterne navn. Vi kan da bruke disse eksterne navnene når funksjonen er kalt til å entydig indikere hvilke argument tilsvarer som parameter. Ta en titt på den oppdaterte eksempelet nedenfor
func makt (base a: Int, eksponent b: Int.) - ≫ Int {var resultat = en for _ i en .. < b {resultat = resultat * a} retur resultat}

Legg merke til at funksjonen kropp ikke har forandret seg siden de lokale navnene ikke har endret seg. Imidlertid, når vi påkalle den oppdaterte funksjon, er forskjellen klar og resultatet mye mindre forvirrende
strøm. (Base: 2, eksponent: 3)

Mens typene begge funksjonene er de samme, (Int, Int ) - > Int, funksjoner er forskjellige. Med andre ord, er den andre funksjonen ikke en redeklarasjon av den første funksjon. Syntaksen til å påberope seg andre funksjonen kan minne noen av dere av Objective-C. Ikke bare er de argumentene tydelig beskrevet, kombinasjonen av funksjon og parameternavn beskrive formålet med funksjonen.

I noen tilfeller vil du bruke de samme navnene for lokale og eksterne parameternavn. Dette er mulig, og det er ikke nødvendig å skrive parameternavnet to ganger. I følgende eksempel bruker vi base og eksponent som de lokale og eksterne parameternavn
func makt (#base: Int, #exponent: Int.) - ≫ Int {var resultat = base for _ i en .. < eksponent {resultat = resultat * basen} retur resultat}

Etter prefixing parameternavnet med # symbol, serverer parameter navn som den lokale og eksterne navn parameter. Dette betyr også at vi må oppdatere kroppen av funksjon.

Det er viktig å merke seg at ved å gi en ekstern navn for en parameter er du pålagt å bruke det navnet når påberope funksjonen. Dette bringer oss til standardverdier.

Standardverdier

Vi dekket standard parameterverdier i den forrige artikkelen, men det er en viktig standard oppførsel at du må være klar over. Hvis du definerer en standardverdi for en parameter, tildeler Swift automatisk en ekstern parameter navn til parameter. La oss se på et eksempel på den forrige artikkelen
func printDate (dato: NSDate, format: String = "YY /MM /dd") - >. String {la dateFormatter = NSDateFormatter () dateFormatter.dateFormat = format retur dateFormatter.stringFromDate (dato)}

Fordi den andre parameteren, format, har en standardverdi, setter Swift automatisk den eksterne parameter navnet format til format. Med andre ord, er resultatet det samme som om vi skulle prefiks format med en # symbol. Du kan teste dette ved å påberope seg over funksjonen i din lekeplass. Hva skjer hvis du passerer i formatet uten å bruke eksterne parameter navnet på den andre parameteren? Svaret er vist nedenfor.

Swift er ganske klar på hva vi bør gjøre. For å oppsummere, når du definerer en parameter som ekstrautstyr, setter Swift automatisk den eksterne parameternavnet til den lokale parameternavnet. Ideen bak denne oppførselen er å unngå forvirring og tvetydighet.

Selv om denne atferden er en god beste praksis, er det mulig å deaktivere den. I den oppdaterte funksjonsdefinisjonen nedenfor, legger vi en understrekning der vi normalt ville legge det ytre parameter navn. Dette forteller Swift at vi ikke ønsker å sette en ekstern parameternavn for den aktuelle parameteren, til tross for at en standardverdi
func formatDate (dato: NSDate, _ format: String = "YY /MM /dd"). - > String {la dateFormatter = NSDateFormatter () dateFormatter.dateFormat = format retur dateFormatter.stringFromDate (dato)}

Vi kan nå påberope seg formatDate funksjonen uten å gi et navn for det andre argumentet.
FormatDate (NSDate (), " dd /MM /ÅÅ ")
2. Parametere & Mutability

La oss se det første eksempelet på denne opplæringen, den printMessage funksjon. Hva skjer hvis vi endrer verdien av meldingen parameter inne funksjonen kropp
func printMessage? (Message: String) {message = "Print: \\ (melding)" println (melding)}

Det tar ikke lang for Swift å begynne å klage.

Som standard parameterne for en funksjon er konstanter. Med andre ord, mens vi kan få tilgang til de verdier av funksjonsparametre, vi kan ikke endre sin verdi. For å endre denne standard oppførsel, legger Var nøkkelord for å parameternavn i funksjonsdefinisjonen. Swift vil deretter opprette en variabel kopi av parameterverdien for deg å jobbe med i funksjonen kropp
func printMessage. (Var budskapet: String) {message = "Print: \\ (melding)" println (melding)}

Merk at dette ikke betyr at du kan passere i en verdi, endre den i funksjon, og bruke den modifiserte verdi etter at funksjonen har gjort sitt arbeid. Swift skaper en kopi av parameterverdien som kun eksisterer for levetiden til funksjonskall. Dette er også illustrert i følgende kode blokken der vi passerer en konstant til printMessage funksjon
func printMessage. (Var budskapet: String) {message = "Print: \\ (melding)" println (melding)} la myMessage = "test" printMessage (myMessage)
3. Variadic Parametere

Mens begrepet kan høres rart i starten, variadic parametre er vanlig i programmering. En variadic parameter er en parameter som tar imot null eller flere verdier. Verdiene må være av samme type. Bruke variadic parametere i Swift er trivielt som følgende eksempel illustrerer
func sum (args: Int ...) - >. Int {var resultat = 0 for en i args {resultat + = a} retur resultat}

Syntaksen er lett å forstå. For å markere en parameter som variadic, føyer du tre prikker til parameter type. I funksjonen kroppen, er variadic parameter tilgjengelig som en matrise. I eksempelet ovenfor, er args en rekke Int verdier.

Fordi Swift trenger å vite hvilke argumenter samsvarer med hvilke parametre, er en variadic parameter som kreves for å bli den siste parameter. Det innebærer også at en funksjon kan ha høyst én variadic parameter.

Dette gjelder også hvis en funksjon har parametere med standardverdier. Den variadic parameter bør alltid være siste parameter.

4. In-Out Parametere

Tidligere i denne opplæringen, lært deg hvordan du kan definere mutability av en parameter ved å bruke VAR søkeord. I denne delen, understreket jeg at verdien av en variabel parameter er kun tilgjengelig fra i funksjonen kroppen. Hvis du ønsker å passere en verdi i en funksjon, endre den i funksjon, og gi det tilbake ut av funksjon, inn-ut parameterne er det du leter etter.

Følgende eksempel viser et eksempel av hvordan in-out parametere jobbe i Swift og hva syntaks ser ut
func prependString (inout a: String, withString b: String). {a = b + a}

Vi har definert den første parameter som en in-out parameter ved å legge til inout søkeord. Den andre parameteren er en vanlig parameter med en ekstern navn på withString og et lokale navnet b. La oss se hvordan vi benytter denne funksjonen
Var verden = "verden" prependString (& verden, withString: "Hei,").

Vi erklærer en variabel, verden, av type String og gi det til perpendString funksjon . Den andre parameteren er en streng bokstavelig. Ved å påberope funksjonen, blir verdien av verden variable Hei, verden. Legg merke til at det første argumentet er prefiks med et ampersand &, for å indikere at det er en in-out parameter.

Det sier seg selv at konstanter og konstanter ikke kan sendes inn som in-out parametere. Swift vil kastet en feil når du gjør som vist i følgende skjermbilde.

Det er tydelig at i-out parametre ikke kan ha standardverdier, være variadic, eller bli definert som VaR eller utleid. Hvis du glemmer disse detaljene, vil Swift ber minne deg med en feilmelding.

5. Nesting

I C og Objective-C, funksjoner og metoder kan ikke nestes. I Swift, men sammenhengende funksjoner er ganske vanlig. Funksjonene vi har sett i denne og den forrige artikkelen er eksempler på globale funksjoner, de er definert i den globale omfang.

Når vi definerer en funksjon inne i en global funksjon, viser vi til at funksjonen som en nestet funksjon. En nestet funksjon har tilgang til de verdiene som er definert i sin omsluttende funksjon. Ta en titt på følgende eksempel for å bedre forstå dette
func printMessage (message: String). {La a = "hello world" func printHelloWorld () {println (a)}}

Mens funksjonene i dette eksemplet er ikke særlig nyttig, illustrerer eksempel ideen om nestet funksjon og fange verdier. Den printHelloWorld funksjonen er bare tilgjengelig fra i printMessage funksjonen. Som illustrert i eksempelet har printHelloWorld funksjon tilgang til en konstant. Verdien fanges opp av den nestede funksjon, og er derfor tilgjengelig fra den funksjonen. Swift tar vare på fange verdier, inkludert administrerende minnet om disse verdiene.

6. Funksjonstyper

I forrige artikkel, vi kort berørt funksjonstyper. En funksjon har en bestemt type, sammensatt av funksjonens parameter typer og dens returtype. Den printMessage funksjon, for eksempel, er av type (String) - > (). Husk at () symboliserer Void, noe som tilsvarer en tom tuppel.

Fordi hver funksjon har en type, er det mulig å definere en funksjon som aksepterer en annen funksjon som parameter. Følgende eksempel viser hvordan dette fungerer
func printMessageWithFunction (message: String, printFunction: (String) - > ()) {printFunction (melding)} la myMessage = "Hei, verden!" PrintMessageWithFunction (myMessage, printMessage).

Den printMessageWithFunction funksjonen aksepterer en streng som første parameter og en funksjon av type (String) - > () Som sin andre parameter. I funksjonen kropp, er funksjonen som vi passerer i påberopes med meldingen argument.

Eksempelet illustrerer også hvordan vi kan påberope seg printMessageWithFunction funksjonen. Den myMessage konstant er gått inn som første argument og printMessage funksjon, som vi definerte tidligere, som det andre argumentet. Hvor kult er ikke det?

Som jeg nevnte tidligere, er det også mulig å returnere en funksjon fra en funksjon. Det neste eksemplet er litt contrived, men det illustrerer hva syntaks ser ut
func beregne (tillegg: Bool.) - ≫ (Int, Int) - > Int {func legge til (a: Int, b: Int) - > Int {return a + b} func subtrahere (a: Int, b: Int) - > Int {return a - b} hvis tillegg {return add} else {return subtrahere}} la computeFunction = beregne (true) la resultat = computeFunction (1, 2) println (resultat)

Den databehandlingsfunksjonen godtar en boolsk og avkastning en funksjon av type (Int, Int) - > Int. Den databehandlingsfunksjonen inneholder to sammenhengende funksjoner som også er av type (int, int) - > Int, legge til og trekke fra.

Den databehandlings funksjonen returnerer en referanse til enten tillegget eller subtrahere funksjon, basert på verdien av å tilsette parameter. Eksempelet viser også hvordan du bruker den databehandlingsfunksjonen. Vi lagrer en referanse til den funksjonen som returneres av databehandlingsfunksjonen i computeFunction konstant. Vi deretter påberope funksjonen lagret i computeFunction, passerer i 1 og 2, lagre resultatet i resultat, og skrive ut verdien av resultat i standard ut. Eksempelet kan se komplisert, men det er faktisk lett å forstå hvis du vet hva som skjer.

Konklusjon

Du skal nå ha en god forståelse av hvordan funksjonene fungerer i Swift og hva du kan gjøre med dem. Funksjoner er et felles tema i Swift og du vil bruke dem mye når du arbeider med Swift.

I neste artikkel, dykke vi hodet først inn nedleggelser, en kraftig konstruksjon som er veldig minner om blokker i C og Objective- C, nedleggelser i Javascript, og lambdaer i Ruby.



Previous:
Next Page: