Swift Language
funktioner
Sök…
Grundläggande användning
Funktioner kan deklareras utan parametrar eller ett returvärde. Den enda information som krävs är ett namn ( hello
i det här fallet).
func hello()
{
print("Hello World")
}
Ring en funktion utan parametrar genom att skriva namnet följt av ett tomt par parentes.
hello()
//output: "Hello World"
Funktioner med parametrar
Funktioner kan ta parametrar så att deras funktionalitet kan ändras. Parametrar ges som en kommaseparerad lista med deras typer och namn definierade.
func magicNumber(number1: Int)
{
print("\(number1) Is the magic number")
}
Obs: Syntaxen \(number1)
är grundläggande stränginterpolering och används för att införa heltalet i strängen.
Funktioner med parametrar anropas genom att ange funktionen med namn och ange ett inmatningsvärde av den typ som används i funktionsdeklarationen.
magicNumber(5)
//output: "5 Is the magic number
let example: Int = 10
magicNumber(example)
//output: "10 Is the magic number"
Vilket värde som helst av typen Int kunde ha använts.
func magicNumber(number1: Int, number2: Int)
{
print("\(number1 + number2) Is the magic number")
}
När en funktion använder flera parametrar krävs inte namnet på den första parametern för den första utan på efterföljande parametrar.
let ten: Int = 10
let five: Int = 5
magicNumber(ten,number2: five)
//output: "15 Is the magic number"
Använd externa parameternamn för att göra funktionssamtal mer läsbara.
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)
Om du ställer in standardvärdet i funktionsdeklarationen kan du ringa funktionen utan att ge några ingångsvärden.
func magicNumber(one number1: Int = 5, two number2: Int = 10)
{
print("\(number1 + number2) Is the magic number")
}
magicNumber()
//output: "15 Is the magic number"
Återvända värden
Funktioner kan returnera värden genom att ange typen efter listan med parametrar.
func findHypotenuse(a: Double, b: Double) -> Double
{
return sqrt((a * a) + (b * b))
}
let c = findHypotenuse(3, b: 5)
//c = 5.830951894845301
Funktioner kan också returnera flera värden med tuples.
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)
Kasta fel
Om du vill att en funktion ska kunna kasta fel måste du lägga till throws
nyckelordet efter parenteserna som innehåller argumenten:
func errorThrower()throws -> String {}
När du vill kasta ett fel, använd throw
nyckelordet:
func errorThrower()throws -> String {
if true {
return "True"
} else {
// Throwing an error
throw Error.error
}
}
Om du vill ringa en funktion som kan kasta ett fel, måste du använda try
sökord i en do
block:
do {
try errorThrower()
}
Mer information om Swift-fel: Fel
metoder
Instansmetoder är funktioner som tillhör instanser av en typ i Swift (en klass , struktur , uppräkning eller protokoll ). Typmetoder kallas på en typ.
Instansmetoder
Instansmetoder definieras med en func
deklaration i definitionen av typen eller i en anknytning .
class Counter {
var count = 0
func increment() {
count += 1
}
}
increment()
-instansmetoden kallas på en instans av Counter
klassen:
let counter = Counter() // create an instance of Counter class
counter.increment() // call the instance method on this instance
Skriv metoder
Typmetoder definieras med de static func
nyckelorden. (För klasser definierar class func
en typmetod som kan åsidosättas av underklasser.)
class SomeClass {
class func someTypeMethod() {
// type method implementation goes here
}
}
SomeClass.someTypeMethod() // type method is called on the SomeClass type itself
Inout-parametrar
Funktioner kan ändra parametrarna som skickas till dem om de är markerade med inout
sökordet. När en inout
parameter inout
till en funktion måste den som ringer lägga till en &
till den variabel som skickas.
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".
Detta gör att referenssemantik kan tillämpas på typer som normalt skulle ha värdesemantik.
Släpningsstängningssyntax
När den sista parametern i en funktion är en stängning
func loadData(id: String, completion:(result: String) -> ()) {
// ...
completion(result:"This is the result data")
}
funktionen kan åberopas med Trailing Closure Syntax
loadData("123") { result in
print(result)
}
Operatörer är funktioner
Operatörer som +
, -
, ??
är en typ av funktion som heter symboler snarare än bokstäver. De åberopas annorlunda än funktioner:
- Prefix:
- x
- Infix:
x + y
- Postfix:
x ++
Du kan läsa mer om grundläggande operatörer och avancerade operatörer i The Swift Programming Language.
Variadiska parametrar
Ibland är det inte möjligt att lista antalet parametrar som en funktion kan behöva. Tänk på en sum
:
func sum(_ a: Int, _ b: Int) -> Int {
return a + b
}
Det här fungerar bra för att hitta summan av två siffror, men för att hitta summan av tre måste vi skriva en annan funktion:
func sum(_ a: Int, _ b: Int, _ c: Int) -> Int {
return a + b + c
}
och en med fyra parametrar skulle behöva en annan, och så vidare. Swift gör det möjligt att definiera en funktion med ett variabelt antal parametrar med hjälp av en sekvens på tre perioder: ...
Till exempel,
func sum(_ numbers: Int...) -> Int {
return numbers.reduce(0, combine: +)
}
Observera hur numbers
parametern, som är variadic, är smält samman till en enda Array
av typen [Int]
. Detta är i allmänhet sant, variadiska parametrar av typ T...
är tillgängliga som en [T]
.
Denna funktion kan nu kallas så:
let a = sum(1, 2) // a == 3
let b = sum(3, 4, 5, 6, 7) // b == 25
En variadisk parameter i Swift behöver inte komma i slutet av parameterlistan, men det kan bara finnas en i varje funktionssignatur.
Ibland är det bekvämt att lägga en minsta storlek på antalet parametrar. Till exempel är det inte vettigt att ta sum
av inga värden. Ett enkelt sätt att genomdriva detta är genom att sätta några obligatoriska parametrar som inte krävs och sedan lägga till den variadiska parametern efter. För att se till att sum
bara kan ringas med minst två parametrar kan vi skriva
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
index
Klasser, strukturer och uppräkningar kan definiera subskript, som är genvägar för att få åtkomst till elementen i en samling, lista eller sekvens.
Exempel
struct DaysOfWeek {
var days = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
subscript(index: Int) -> String {
get {
return days[index]
}
set {
days[index] = newValue
}
}
}
Prenumerationsanvändning
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])
Alternativ för prenumerationer:
Abonnemang kan ta valfritt antal ingångsparametrar, och dessa inmatningsparametrar kan vara av valfri typ. Abonnemang kan också returnera valfri typ. Abonnemang kan använda variabla parametrar och variadiska parametrar, men kan inte använda in-out-parametrar eller tillhandahålla standardparametervärden.
Exempel:
struct Food {
enum MealTime {
case Breakfast, Lunch, Dinner
}
var meals: [MealTime: String] = [:]
subscript (type: MealTime) -> String? {
get {
return meals[type]
}
set {
meals[type] = newValue
}
}
}
Användande
var diet = Food()
diet[.Breakfast] = "Scrambled Eggs"
diet[.Lunch] = "Rice"
debugPrint("I had \(diet[.Breakfast]) for breakfast")
Funktioner med stängningar
Att använda funktioner som tar in och utför stängningar kan vara extremt användbart för att skicka ett kodblock som ska köras någon annanstans. Vi kan börja med att låta vår funktion ta in en valfri stängning som (i detta fall) kommer att returnera Void
.
func closedFunc(block: (()->Void)? = nil) {
print("Just beginning")
if let block = block {
block()
}
}
Nu när vår funktion har definierats, låt oss kalla den och skicka in någon kod:
closedFunc() { Void in
print("Over already")
}
Genom att använda en släpstängning med vårt funktionssamtal kan vi skicka in kod (i detta fall, print
) som ska köras vid någon punkt inom vår closedFunc()
-funktion.
Loggen ska skriva ut:
Bara börjar
Över redan
Ett mer specifikt användningsfall av detta kan inkludera körning av kod mellan två klasser:
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?()
}
}
Loggen ska skriva ut:
1
2
Passerar och returnerar funktioner
Följande funktion returnerar en annan funktion som resultat som senare kan tilldelas en variabel och kallas:
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)
Funktionstyper
Varje funktion har sin egen funktionstyp, som består av parametertyperna och själva funktionens returtyp. Till exempel följande funktion:
func sum(x: Int, y: Int) -> (result: Int) { return x + y }
har en funktionstyp av:
(Int, Int) -> (Int)
Funktionstyper kan således användas som parametertyper eller som returtyper för häckningsfunktioner.