在下面的图片中,您可以看到在操场上执行的代码感觉不对。但Swift编译器完全没问题。由于某种原因,元组的嵌入深度减少到一个。
更具表现力:
有人知道这是一个错误还是一个功能?
答案 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)`.
现在,为什么第一个地图关闭失败,而第二个不关闭?
使用尾随闭包时,您可以
$0
,...)或两个示例都尝试使用命名参数,但只有第二个示例遵循使用名称参数的规则:即必须提供参数名称(提供参数 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)
),在这种情况下,编译器需要包含内部参数名称或明确省略一个(使用_
)。只有当您提供参数名称时,编译器才会意识到x
和y
不是有效类型。
在你的第二个例子中,你只需将两个元组成员的闭包直接绑定到内部参数名x
和y
,选择不显式键入注释这些参数(这没关系)。