Swift notes function

  • 2020-05-10 22:59:28
  • OfStack

parameter

External variable name

1 in general, you can call a function without specifying an external variable name:


func helloWithName(name: String, age: Int, location: String) {
    println("Hello \(name). I live in \(location) too. When is your \(age + 1)th birthday?")
}
helloWithName("Mr. Roboto", 5, "San Francisco")

But in a class (or struct, enumeration), the name of the external variable is automatically assigned (except for the first one), and an error is reported if you want to call it directly:


class MyFunClass { 
    func helloWithName(name: String, age: Int, location: String) {
        println("Hello \(name). I live in \(location) too. When is your \(age + 1)th birthday?")
    }
}
let myFunClass = MyFunClass()
myFunClass.helloWithName("Mr. Roboto", 5,  "San Francisco")

If you miss the way you defined a function name in OC, you can continue to define it like this, such as helloWithName, by hiding the external name of the first function:


class MyFunClass {
    func helloWithName(name: String, age: Int, location: String) {
        println("Hello \(name). I live in \(location) too. When is your \(age + 1)th birthday?")
    }
}
let myFunClass = MyFunClass()
myFunClass.helloWithName("Mr. Roboto", age: 5, location: "San Francisco")

If you really don't want an external variable name, use _ instead:


struct Celsius {
    var temperatureInCelsius: Double
    init(fromFahrenheit fahrenheit: Double) {
        temperatureInCelsius = (fahrenheit - 32.0) / 1.8
    }
    init(fromKelvin kelvin: Double) {
        temperatureInCelsius = kelvin - 273.15
    }
    init(_ celsius: Double) {
        temperatureInCelsius = celsius
    }
}
let boilingPointOfWater = Celsius(fromFahrenheit: 212.0)
// boilingPointOfWater.temperatureInCelsius is 100.0
let freezingPointOfWater = Celsius(fromKelvin: 273.15)
// freezingPointOfWater.temperatureInCelsius is 0.0
let bodyTemperature = Celsius(37.0)
// bodyTemperature.temperatureInCelsius is 37.0

Skilled use of external parameter names makes for an excellent abstraction of the initialization process. Check out the json-swift library application.

Default parameter value

You can write the default value of the function in the function definition so that it is not passed when you call it:


func add(value1 v1:Int, value2 p1:Int = 2) -> Int{
    return v1 + p1
}
add(value1: 2, value2: 4)   // 2 + 4
add(value1: 1)  // 1 + 2

If you do not provide the external parameter name, setting the default parameter value will automatically provide the default parameter name.

Variable parameter

Variable parameters (Variadic Parameters) can accept more than one parameter value. For example, calculate the average:


func arithmeticMean(numbers: Double...) -> Double {
    var total: Double = 0
    for number in numbers { // numbers is [Double]
        total += number
    }
    return total / Double(numbers.count)
}
arithmeticMean(1, 2, 3, 4, 5)
arithmeticMean(3, 8, 19)

If you have more than one parameter, you need to put the variable at the end, otherwise you will get an error. It should look like this:


func sumAddValue(addValue:Int=0, numbers: Int...) -> Int {
    var sum = 0
    for number in numbers { // numbers === [Int]
        sum += number + addValue
    }
    return sum
}
sumAddValue(addValue: 2, 2,4,5) // (2+2) + (4+2) + (5+2) = 17

Constant and variable parameters

The default parameter is constant and cannot be changed in the body of the function. We can use var with a new value, or we can simply add var to the function definition to avoid defining a new variable in the body of the function.

For example, this 1 right-aligned function:


func alignRight(var string: String, count: Int, pad: Character) -> String {
    let amountToPad = count - countElements(string)
    if amountToPad < 1 {
        return string
    }
    let padString = String(pad)
    for _ in 1...amountToPad {
        string = padString + string
    }
    return string
}
let originalString = "hello"
let paddedString = alignRight(originalString, 10, "-")  // "-----hello"

Input/output parameters (inout)

Changes made to variable parameters in the body of the function do not change the parameter values themselves, as shown in this example:


func add(var v1:Int) -> Int {
    return ++v1
}
var a = 1
add(a)      // 2
a           // 1

If you want to modify the original value through the function, you need inout, but this is wrong:


func add(inout v1:Int) -> Int {
    return ++v1
}
var a = 1
add(a)      // 2
a           // 1

When passing in, you need to add & :


func add(inout v1:Int) -> Int {
    return ++v1
}
var a = 1
add(&a)      // 2
a           // 1

Generic parameter types

Use the example from objc.io below 1 to demonstrate the use of generic parameter types:


// A function of swapping two values
func valueSwap<T>(inout value1: T, inout value2: T) {
    let oldValue1 = value1
    value1 = value2
    value2 = oldValue1
}
var name1 = "Mr. Potato"
var name2 = "Mr. Roboto"
valueSwap(&name1, &name2)   // Interchange string
name1 // Mr. Roboto
name2 // Mr. Potato
var number1 = 2
var number2 = 5
valueSwap(&number1, &number2)   // Exchange of digital
number1 // 5
number2 // 2

Function types

In Swift, the function turns and sings, finally becoming a class 1 citizen, on a par with other types.

variable

We can define a variable whose type is the function type:


func addTwoInts(a: Int, b: Int) -> Int {
    return a + b
}
let anotherMathFunction = addTwoInts
anotherMathFunction(1,2)    // 3

parameter

Since a function is a type, it can also be passed as a parameter:


func addTwoInts(a: Int, b: Int) -> Int {
    return a + b
}
func printMathResult(mathFunction: (Int, Int) -> Int, a: Int, b: Int) {
    println("Result: \(mathFunction(a, b))")
}
printMathResult(addTwoInts, 3, 5)   // The parameter 2 And parameters 3 Pass as a parameter to the parameter 1 The function of

The return value

Functions can also be returned as results. For example, if the return value is a function whose return value is Int with the parameter Int, it is defined as func foo() - > (Int) - > Int. Here's a concrete example:


func stepForward(input: Int) -> Int {
    return input + 1
}
func stepBackward(input: Int) -> Int {
    return input - 1
}
func chooseStepFunction(backwards: Bool) -> (Int) -> Int {
    return backwards ? stepBackward : stepForward
}
var currentValue = 3
let moveNearerToZero = chooseStepFunction(currentValue > 0) // Return by parameter stepForward or stepBackward
println("Counting to zero:")
while currentValue != 0 {
    println("\(currentValue)... ")
    currentValue = moveNearerToZero(currentValue)
}
println("zero!")
// 3...
// 2...
// 1...
// zero!

The alias

If you use it too much, you'll find it in the 1 string ()- > Interspersed with various ()- > It's a very painful thing. We can use typealias to define the function alias, and its function is basically the same as typedef in OC and alias in shell. Here's an example:


import Foundation
typealias lotteryOutputHandler = (String, Int) -> String
// If there is no typealias Here's what you need:
// func luckyNumberForName(name: String, #lotteryHandler: (String, Int) -> String) -> String {
func luckyNumberForName(name: String, #lotteryHandler: lotteryOutputHandler) -> String {
    let luckyNumber = Int(arc4random() % 100)
    return lotteryHandler(name, luckyNumber)
}
luckyNumberForName("Mr. Roboto", lotteryHandler: {name, number in
    return "\(name)'s' lucky number is \(number)"
})
// Mr. Roboto's lucky number is 33

nested

But not all functions need to be exposed. Sometimes we define a new function just to encapsulate a layer, not to reuse it. This is where you can nest functions, as in the previous example:


func chooseStepFunction(backwards: Bool) -> (Int) -> Int {
    func stepForward(input: Int) -> Int { return input + 1 }
    func stepBackward(input: Int) -> Int { return input - 1 }
    return backwards ? stepBackward : stepForward
}
var currentValue = -4
let moveNearerToZero = chooseStepFunction(currentValue < 0)
// moveNearerToZero now refers to the nested stepForward() function
while currentValue != 0 {
    println("\(currentValue)... ")
    currentValue = moveNearerToZero(currentValue)
}
println("zero!")
// -4...
// -3...
// -2...
// -1...
// zero!

Currie (currying)

The basic idea behind coriolization is that functions can be applied locally, meaning that some parameter values can be specified or bound before the function is called. This partial function call returns a new function.

This can be seen in the coriolization section of the multifaceted Swift method. We can call:


class MyHelloWorldClass {
    func helloWithName(name: String) -> String {
        return "hello, \(name)"
    }
}
let myHelloWorldClassInstance = MyHelloWorldClass()
let helloWithNameFunc = MyHelloWorldClass.helloWithName
helloWithNameFunc(myHelloWorldClassInstance)("Mr. Roboto")
// hello, Mr. Roboto

The return value more

In Swift we can use tuple to return multiple return values. For example, the following example returns the range of all Numbers:


class MyFunClass { 
    func helloWithName(name: String, age: Int, location: String) {
        println("Hello \(name). I live in \(location) too. When is your \(age + 1)th birthday?")
    }
}
let myFunClass = MyFunClass()
myFunClass.helloWithName("Mr. Roboto", 5,  "San Francisco")
8

While the return value may not always have a value, we can also return results of optional types:


class MyFunClass { 
    func helloWithName(name: String, age: Int, location: String) {
        println("Hello \(name). I live in \(location) too. When is your \(age + 1)th birthday?")
    }
}
let myFunClass = MyFunClass()
myFunClass.helloWithName("Mr. Roboto", 5,  "San Francisco")
9

That's all for this article, I hope you enjoy it.


Related articles: