简体   繁体   中英

How to use tuples effectively in function?

Swift programming book says,

By returning a tuple with two distinct values, each of a different type, the function provides more useful information about its outcome than if it could only return a single value of a single type.

Excerpt From: Apple Inc. “The Swift Programming Language.” iBooks. https://itun.es/gb/jEUH0.l

I searched on internet but couldn't find any examples of it.So I tried myself like example below, but if you've got better please let me know.. Thanks in advance.

var statusCode = 404
var statusMessage = "No Site"

let http404 = ( sCode : statusCode , sMessage : statusMessage)

func responseFromWS (foo : Int, bar : String) -> (param1 : Int, param2 : String)
{
    statusCode = foo
    statusMessage = bar

    let httpProtocol = ( statusCode , statusMessage)

    return httpProtocol
}


responseFromWS(500, "Internal Server Error")

输出量

In other languages (including objective c) you can return one value only (of any type), but in some cases you might need to return more than one value.

The pattern usually applied in those cases is to pass references to variables to the function for all additional return values - a typical case is a reference to a NSError * variable, which the function either sets to nil if no error occurs, or to an instance of NSError in case of error.

Such problem is elegantly solved in swift using multiple return values packed in a tuple.

The way you are using this features seems correct, but what's wrong is defining the statusCode and statusMessage variables outside the function scope:

func responseFromWS (foo : Int, bar : String) -> (code: Int, message: String)
{
    let statusCode: Int = foo
    let statusMessage: String = bar

    return (code: statusCode, message: statusMessage)

    // Note: you can also write as follows, because the parameter names are defined in the function signature
    // return (statusCode, statusMessage)
}

You can use the return value in different ways. As a tuple:

let response = responseFromWS(500, "Internal Server Error")

// Using named parameters
println(response.code) // Prints 500
println(response.message) // Prints "Internal Server Error"

// using parameters by index
println(response.0) // Prints 500
println(response.1) // Prints "Internal Server Error"

As individual variables:

let (code, message) = responseFromWS(500, "Internal Server Error")

println(code)
println(message)

As a subset of individual variables (if you need only a subset of the returned values):

// Assign message only, discard code
let (_, message) = responseFromWS(500, "Internal Server Error")

println(message)

In addition to the uses mentioned by @Antonio, I have used them to return "pseudo-structs" where a function calculates several values, but the definition of a new struct type would really not be used anywhere else.

An example: when calculating true bearing and distance on the surface of the earth, one may choose to return some kind of polar coordinate struct, but the reverse azimuth (not a trivial relation in true geodesy) is also calculated as a by product. In implementations in other languages I have done this by defining a struct type to return the three doubles - but this struct type is never used except to call this function! Better to say

let (distance, azimuth, reverseAzimuth) = coordinate(vectorTo: otherCoordinate)

than having your future self look up the definition of and then unpack some obscure struct.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM