我正在尝试确定.map输出的类型在哪里:
func position(rows: Int, cols: Int) -> [Position] {
return (0 ..< rows)
.map {
zip(
[Int](repeating: $0, count: cols) ,
0 ..< cols
)
}
}
我知道zip返回一个Zip2Sequence实例,在这种情况下是元组对(整数数组,可数整数范围)。
我得到的地图改变了序列中的元素,但我认为它需要多个参数,如val in val * 2
,这里zip是唯一的参数......所以它只是将zip的输出添加到数组中? / p>
答案 0 :(得分:1)
map
的结果属于Array<Zip2Sequence<Array<Int>, CountableRange<Int>>>
类型,基本上是[[(Int, Int)]]
。
我通过将map
的结果分配到let result
并打印print(type(of: result))
来找到这一点。
map
将原始序列(0 ..< rows)
转换为具有rows
项的数组。 zip
的每个元素将依次调用(0 ..< rows)
,由$0
表示。
如果您使用zip
打包Array()
来将zip序列转换为可以轻松检查的实际数组,那将会更有用:
示例:
let rows = 2
let cols = 3
let result = (0 ..< rows)
.map { val in
Array(zip(
[Int](repeating: val, count: cols) ,
0 ..< cols
))
}
print(result)
// [[(0, 0), (0, 1), (0, 2)], [(1, 0), (1, 1), (1, 2)]]
答案 1 :(得分:1)
(0 ..< rows)
的类型为CountableRange<Int>
:
1> (0 ..< 10)
$R0: (CountableRange<Int>) = {
lowerBound = 0
upperBound = 10
}
CountableRange
符合Sequence
,因此它有map
方法。这个map
方法接受一个参数,一个闭包。
闭包是一种功能。通常,函数具有零个或多个参数以及一个返回值。对于CountableRange<Int>.map
,闭包需要采用类型为Int
的一个参数,并且可以返回任何类型。
有几种方法可以在Swift中编写闭包。您的示例使用的最短路径是在{ ... }
内编写单个表达式。以下是The Swift Programming Language (Swift 4)所说的内容:
单表达式闭包的隐式返回
单表达式闭包可以通过从声明中省略return关键字来隐式返回单个表达式的结果[...]
此外,如果闭包采用参数,闭包可以使用简写名称($0
,$1
等)引用它们。而不是给它们显式名称(例如val in ...
)。再次出书:
速记参数名称
Swift自动为内联闭包提供简写参数名称,可用于通过名称
$0
,$1
,$2
等来引用闭包参数的值。如果在闭包表达式中使用这些简写参数名称,则可以从其定义中省略闭包的参数列表,并且将从期望的函数类型推断出简写参数名称的数量和类型。
in
关键字也可以省略,因为闭包表达式完全由它的主体组成[...]
查看map
方法调用,我们可以看到它的闭包包含一个带有隐式返回的表达式(对zip
的调用),它使用$0
来引用它单一论点。
zip
函数有两个参数,每个参数必须是Sequence
,zip
函数返回Zip2Sequence
。在您的示例中,zip
的第一个参数是[Int](repeating: $0, count: cols)
,其类型为[Int]
(或Array<Int>
)。 zip
的第二个参数是0 ..< cols
,这是另一个CountableRange<Int>
。因此,此zip
调用返回的类型为Zip2Sequence<[Int], CountableRange<Int>>
,这是一种有点不可思议的类型,可生成元组(Int, Int)
。
map
返回的类型是Array
,包含其closure参数返回的值。因此,在这种情况下map
返回的类型为[Zip2Sequence<[Int], CountableRange<Int>>]
。
如果你想要更具灵活性的东西,你可以将调用包裹在zip
构造函数中的Array
:
func position(rows: Int, cols: Int) -> [[(Int, Int)]] {
return (0 ..< rows)
.map {
Array(zip(
[Int](repeating: $0, count: cols) ,
0 ..< cols
))
}
}
Array
构造函数接受任何Sequence
并将其转换为Array
。因此,Zip2Sequence<[Int], CountableRange<Int>>
变为[(Int, Int)]
,map
生成Array
,其元素属于该类型,从而生成一对Int
对的数组,或[[(Int, Int)]]
。