[Swift] Day06: Function

Source: Internet
Author: User

[Swift] Day06: Function
Function parameter external variable name

Generally, you can directly call a function without specifying the 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")

However, when the class (or structure or enumeration) is used, the external variable name (except the first one) will be automatically assigned. If you want to call it directly, an error will be reported:

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 defining the function name in OC, you can continue to define it like this, for examplehelloWithNameIn this way, the external name of the first function is hidden:

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, you can use_To replace:

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

Skillful Use of External Parameter names can perfectly abstract the initialization process. Let's take a look at the applications in the json-swift library.

Default parameter value

You can write the default value of the function in the function definition so that you do not need to pass this value during the call:

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

If you do not provide an external parameter name, the default parameter name is automatically provided when the default parameter value is set.

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 there are more than one parameter, you must put the variable parameter at the end. Otherwise, an error is returned. It should be 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 a constant and cannot be changed in the function body. We canvarYou can add a new value to the function definition.varAvoid defining new variables in the function body.

For example, this right alignment 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)

Modifying the variable parameter in the function body does not change the parameter value itself. For example, let's look at this example:

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

If you want to use the function to modify the original valueinoutBut this is incorrect:

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

You must add&MARK:

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

Here we use the example in objc. io to demonstrate the usage of generic parameter types:

// Function for exchanging two values: func valueSwap
 
  
(Inout value1: T, inout value2: T) {let oldValue1 = value1 value1 = value2 value2 = oldValue1} var name1 = "Mr. potato "var name2 =" Mr. roboto "valueSwap (& name1, & name2) // exchange string name1 // Mr. robotoname2 // Mr. potatovar number1 = 2var number2 = 5 valueSwap (& number1, & number2) // exchange the number number1 // 5number2 // 2
 
Function Type

In Swift, the function turned to sing and finally became a first-class citizen.

Variable

We can define a variable whose type is function:

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

Since a function is of 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) // PASS Parameters 2 and 3 as the parameters to the function of parameter 1
Return Value

Functions can also be returned as results. For example, if the returned value is a function whose parameter is Int and the returned value is Int, it is defined as follows:func foo() -> (Int) -> Int. See the following 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 = 3let moveNearerToZero = chooseStepFunction (currentValue> 0) // return stepForward or stepBackwardprintln ("Counting to zero:") while currentValue! = 0 {println ("\ (currentValue)...") currentValue = moveNearerToZero (currentValue)} println ("zero! ") // 3 .. // 2 .. // 1 .. // zero!
Alias

If you use more, you will find that()->Interspersed with various()->It is a very painful thing. We can usetypealiasDefine the function alias. Its function is basically the same as typedef in OC and alias in shell. For example:

Import Foundationtypealias lotteryOutputHandler = (String, Int)-> String // This is required if no typealias is available: // func luckyNumberForName (name: String, # lotteryHandler: (String, Int) -> String)-> String {func luckyNumberForName (name: String, # lotteryHandler: lotteryOutputHandler)-> String {let luckyNumber = Int (arc4random () % 100) return teryhandler (name, luckyNumber)} luckyNumberForName ("Mr. roboto ", lotteryHandler: {name, number in return" \ (name)'s 'lucky number is \ (number) "}) // Mr. roboto's lucky number is 33
Nesting

But not all functions need to be exposed. Sometimes we define a new function to encapsulate a layer, not to reuse it. In this case, the function can be nested, for example, 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 = -4let moveNearerToZero = chooseStepFunction(currentValue < 0)// moveNearerToZero now refers to the nested stepForward() functionwhile currentValue != 0 {    println("\(currentValue)... ")    currentValue = moveNearerToZero(currentValue)}println("zero!")// -4...// -3...// -2...// -1...// zero!
Currying)

The basic idea behind keri Is that a function can be applied locally, meaning that some parameter values can be specified or bound before the function is called. This part of the function calls will return a new function.

For details, refer to the multi-faceted section of the Swift method. We can call it like this:

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

In Swift, we can use tuple to return multiple return values. For example, in the following example, the range of all numbers is returned:

 func findRangeFromNumbers(numbers: Int...) -> (min: Int, max: Int) {    var maxValue = numbers.reduce(Int.min,  { max($0,$1) })    var minValue = numbers.reduce(Int.max,  { min($0,$1) })     return (minValue, maxValue)}findRangeFromNumbers(1, 234, 555, 345, 423)// (1, 555)

The returned values may not all have values. We can also return optional results:

import Foundationfunc componentsFromUrlString(urlString: String) -> (host: String?, path: String?) {    let url = NSURL(string: urlString)    return (url?.host, url?.path)}let urlComponents = componentsFromUrlString("http://why/233;param?foo=1&baa=2#fragment")switch (urlComponents.host, urlComponents.path) {case let (.Some(host), .Some(path)):    println("host \(host) and path \(path)")case let (.Some(host), .None):    println("only host \(host)")case let (.None, .Some(path)):    println("only path \(path)")case let (.None, .None):    println("This is not a url!")}// "host why and path /233/param"
References
  • Functions
  • Swift Functions
  • The diversity of Swift Methods
  • Instance Methods are Curried Functions in Swift

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.