理解为什么不允许这个Swift元组赋值

时间:2016-10-06 03:25:07

标签: swift tuples swift3

以下代码没问题:

func intTest() -> Int? {
    var res : Int

    res = 5

    return res
}

从返回类型为Int的方法返回非可选Int没有问题。

现在让我们看看当返回值是可选值的元组时会发生什么:

func tupleTest() -> (Int?, Int?) {
    var res : (Int, Int)

    res = (5, 5)

    return res
}

return res行导致错误:

  

错误:无法将元组转换'(Int,Int)'表示为'(Int?,Int?)'(又名'(可选,可选)')

为什么Swift不允许这样做?

我当然理解为什么这会是另一个方向的错误(非可选的可选)但是为什么当非元组工作正常时,元组不能在可选的位置接受非可选值?

我见过Swift tuple to Optional assignment,但这并没有说明为什么你不能完成任务,它只是解决了如何解决它。

1 个答案:

答案 0 :(得分:7)

发生这种情况的原因是由于类型不匹配。考虑以下情况:

let myClosure: (Int) -> ()
let myOtherClosure: (Int?) -> ()

myClosure的类型为(Int) -> (),而myOtherClosure的类型为(Int?) -> (),这使得它们基本上是不同的类型,尽管参数相似。当Swift查看这两个常量时,它会评估整个类型,而不是单个部分。你的元组也是如此;它将元组类型签名视为一个整体,而不是分解参数并认识到它们是同一类型的非可选版本。

Int转换为Int?是有效的,因为它们属于同一类型,一个只是可选的。从(Int, Int)(Int?, Int?)不会因为元组的参数不同而导致整体类型不同,从而导致错误。

看看你的一个例子:

 func tupleTest() -> (Int?, Int?) {
    let first: Int = 1
    let second: Int = 2
    let res: (Int?, Int?) = (first, second)
    return res
 }

这是有效的,因为即使值是非可选整数,元组类型也会标记为(Int?, Int?)而是:

func tupleTest() -> (Int?, Int?) {
    let first: Int = 1
    let second: Int = 2
    let res = (first, second)
    return res
}

无法编译,因为现在res的类型为(Int, Int)。我不是Swift编译器的专家,但我的猜测是类型系统的工作方式是它不解构函数或元组的每个部分,并认识到相应的返回参数是相同的类型,只是一个可选的。