斯威夫特奇怪的元组翻译

时间:2016-11-03 22:47:22

标签: swift functional-programming tuples swift-playground

在下面的图片中,您可以看到在操场上执行的代码感觉不对。但Swift编译器完全没问题。由于某种原因,元组的嵌入深度减少到一个。

更具表现力:

  • 第一次映射调用导致编译错误。 (的奇怪!
  • 第二个电话没问题。 (的奇怪!

有人知道这是一个错误还是一个功能?

Playground example

1 个答案:

答案 0 :(得分:1)

(Int, Int)是一个元组类型(其中parantheses是其类型的一部分),就像((Int, Int))是相同的元组类型一样,但是包含在一对额外的(冗余)parantheses中,就像(((Int, Int)))与前两个元组的元组类型相同,但包含在两组(冗余)parantheses中。

var a: (((Int, Int)))
print(type(of: a)) // (Int, Int)

如果您在嵌套级别上开始组合不同类型,则其他parantheses才会生效,例如

var a: ((Int, Int), Int)
print(type(of: a)) // ((Int, Int), Int)`.

现在,为什么第一个地图关闭失败,而第二个不关闭?

使用尾随闭包时,您可以

  1. 使用简写参数名称($0,...)或
  2. 使用显式命名(或显式名称省略,'_')参数。
  3. 两个示例都尝试使用命名参数,但只有第二个示例遵循使用名称参数的规则:即必须提供参数名称(提供参数 types 和闭包返回类型是可选,但在某些情况下由于编译器类型推断限制而需要。)

    研究以下例子:

    /* all good */
    arr.map { (a) in
        2*a /* ^-- explicitly name parameter */
    }
    
    // or
    arr.map { a in
        2*a /* ^-- explicitly name parameter */
    }
    
    /* additional parantheses: 
           error: unnamed parameters must be written with the empty name '_'
    
       the closure now believes we want to supply parameter name as well as 
       an explicit type annotation for this parameter */
    arr.map { ((a)) in
        2*a /*  ^-- compiler believes this is now a _type_, and prior to realizing 
                    that it is not, prompts us for the error that we have not 
                    supplied a parameter name/explicly omitted one with '_' */
    }
    
    /* additional parantheses: 
           error: use of undeclared type 'a' */
    arr.map { (_: (a)) in
        1   /* ^-- type omitted: compiler now realize that 'a' is not a type */
    }
    
    /* fixed: all good again! */
    arr.map { (_: (Int)) in
        1
    }
    

    在你的第一个例子中,将你的元组包装在tousele元素的尝试命名中(在闭包的.... in部分中)在paranthesis 中(就像上面显示的错误一样),这意味着Swift认为它是类型(类型(x, y)),在这种情况下,编译器需要包含内部参数名称或明确省略一个(使用_)。只有当您提供参数名称时,编译器才会意识到xy不是有效类型。

    在你的第二个例子中,你只需将两个元组成员的闭包直接绑定到内部参数名xy,选择不显式键入注释这些参数(这没关系)。