Swift中的元组和函数参数

时间:2015-07-09 14:37:53

标签: swift tuples

在Swift中,元组与函数参数有什么关系?

在以下两个示例中,函数返回相同的类型,即使一个采用元组而另一个采用两个参数。从调用者的角度来看(没有偷看代码),函数是否采用元组或常规参数没有区别。

函数参数在某些方面与元组有关吗?

e.g。

func testFunctionUsingTuple()->(Int, String)->Void {
    func t(x:(Int, String)) {
        print("\(x.0) \(x.1)")
    }

    return t
}

func testFuncUsingArgs()->(Int, String)->Void {
    func t(x:Int, y:String) {
        print("\(x) \(y)")
    }

    return t
}

do {
    var t = testFunctionUsingTuple()
    t(1, "test")
}

do {
    var t = testFuncUsingArgs()
    t(1, "test")
}

在常规函数(而不是返回函数)中声明函数参数中的元组时,行为也存在不一致:

func funcUsingTuple(x:(Int, String)) {
    print("\(x.0) \(x.1)")
}

func funcUsingArgs(x:Int, _ y:String) {
    print("\(x) \(y)")
}

// No longer works, need to call funcUsingTuple((1, "test")) instead
funcUsingTuple(1, "test")   
funcUsingArgs(1, "test3")

更新:

Chris Lattner关于元组的澄清:

  

" x.0“其中x是标量值,由于奇数,产生标量值   涉及标量和标量之间过度隐式转换的行为   元组。这是一个需要修复的错误。

     

在"让x =(y)“,x和y具有相同的类型,因为(x)是   括号(即分组)运算符的语法,而不是元组   编队运营商。没有单一元素这样的东西   未标记的元组值。

     

In"(foo:42)“ - 这在参数列表中最常见 -   你正在生成一个带元素标签的元素元组。   编译器目前正在努力消除它们并降级   他们是标量,但不一致(这也是一个错误)。   也就是说,单元素标记的元组是一个东西。

2 个答案:

答案 0 :(得分:4)

每个函数都只包含一个包含函数参数的元组。这包括没有参数的函数,它将() - 空元组 - 作为它的一个参数。

以下是Swift编译器如何将各种paren表单转换为内部表示形式:

() -> Void
(x) -> x
(x, ...) -> [Tuple x ...]

并且,如果有tuple?函数,则会返回true:VoidX[Tuple x ...]

这是你的证据:

let t0 : () = ()
t0.0 // error

let t1 : (Int) = (100)
t1.0 -> 100
t1.1 // error

let t2 : (Int, Int) = (100, 200)
t2.0 -> 100
t2.1 -> 200
t2.2 // error

[大胆地说,没有Swift口译员可以访问。]

来自AirSpeedVelocity

  

但是等等,你问,如果我传递了一个除了元组以外的东西怎么办?   好吧,我回答(用一种深刻的哲学基调),真正的是什么   变量,如果不是一个元素的元组? Swift中的每个变量都是   1元组。实际上,每个非元组变量都具有.0属性   该变量的值.4打开一个游乐场并试一试。因此,如果   你将一个非元组变量传递给TupleCollectionView,它是合法的   因为它像一个人的集合。如果你不相信,请阅读   那个听起来真实的人的声音再次证明了这一点   自信。

记住哲学基调'因为我们已经达到了“我说马铃薯”;你说土豆'相。

答案 1 :(得分:1)

Swift中的函数将元组作为参数,可以包含零个或多个值。无参数函数采用没有值的元组,带有一个参数的函数采用带有1值的元组等。

您可以通过单独传递参数或将它们分组到不可变元组来调用函数。例如,所有这些调用都是等效的:

do {
    let t1 = testFunctionUsingTuple()
    let t2 = testFuncUsingArgs()

    let params = (1, "tuple test")

    t1(params)
    t1(2, "test")

    t2(params)
    t2(3, "test")
}