.map转换闭包引起的混乱

时间:2019-06-09 01:50:18

标签: swift

下面的代码可以编译并运行正常,并且似乎表明closureString.init(describing:)函数的签名完全相同,因为.map方法很高兴地接受了这两个函数。 / p>

let someDict: [String: String] = [
    "string1" : "Hello",
    "string2" : "Bye",
]

//One way to call .map
var closure = { (key: String, value: String) -> String in
    return "The key is \(key), the value is \(value)"
}
someDict.map(closure)

//Another way to call .map
someDict.map(String.init(describing:))

但是如何将.map函数放到String.init(describing:)中,该函数仅包含1个参数,而.map期望包含2个参数?还是我误会了这里的东西。

顺便说一句,检查文档表明它确实确实希望有2个参数的函数:

transform: ((key: String, value: String)) throws -> T

1 个答案:

答案 0 :(得分:1)

  

顺便说一句,检查文档表明它确实确实期望   2个参数的功能:

transform: ((key: String, value: String)) throws -> T

实际上,不。注意多余的括号()。它表明它期望一个带有一个参数的函数,该参数是一个包含两个元素的元组。

考虑以下示例:

// function foo takes two arguments
func foo(_ a: Int, _ b: Int) -> Int {
    return a + b
}

// function bar takes one tuple with two elements
func bar(_ a: (Int, Int)) -> Int {
    return a.0 + a.1
}

let f1 = foo
print(type(of: f1))  // (Int, Int) -> Int

let f2 = bar
print(type(of: f2))  // ((Int, Int)) -> Int

因此,多余的括号告诉我们map期望一个参数,它是一个包含两个元素的元组。

传递给map的闭包总是一次处理序列中的单个元素。该元素可以是元组,例如您的案例,然后您的闭包可以将其元组解构成多个值。

考虑以下示例:

// tup is a tuple containing 3 values
let tup = (1, true, "hello")

// deconstruct the tuple through assignment
let (x, y, z) = tup

print(x)  // 1
print(y)  // true
print(z)  // hello

因此在此示例中:

var closure = { (key: String, value: String) -> String in
    return "The key is \(key), the value is \(value)"
}
someDict.map(closure)

map的闭包具有(key: String, value: String)形式的元组,闭包正像key那样将其解构为valuelet以上。

在此示例中:

someDict.map(String.init(describing:))

等效于:

someDict.map({ String(describing: $0) })

map将整个元组传递给String(describing:)