Swift 4.2怪异-.map-行为

时间:2019-01-13 10:02:35

标签: swift collections

在Swift 4.2中的集合上使用.map时遇到一些麻烦。 这是正在发生的事情:

我有一个这样声明的属性:

var cbPerifList:[CBPeripheral]!

稍后我写代码时:

_ = cbPerifList.map { (perif) -> Void in
    print(perif.identifier)
}

编译器看起来很高兴,没有抱怨。

但是当我写:

_ = cbPerifList.map { (perif) -> Void in
    print(perif.identifier)
    print("HELLO")
}

编译器通过显示此消息进行投诉。

Value of type '[CBPeripheral]' has no member 'identifier'

在代码行上: print(perif.identifier)

有人可以解释这里发生了什么吗?

  1. 我不明白为什么添加这一行代码会有所作为。

    print(“ HELLO”)

  2. 我希望perif的类型为CBPeripheral,而不是错误消息所述的[CBPeripheral]。

2 个答案:

答案 0 :(得分:4)

如其他答案和注释中所述,使用forEachfor ... in是遍历数组的正确方法。

但是要回答您的问题并解释为什么那些看似相同的代码片段的行为会有所不同:这是由以下事实共同造成的:

在“单一陈述”中

_ = cbPerifList.map { (perif) -> Void in
    print(perif.identifier)
}

编译器尝试从print表达式推断出闭合类型,并且为了键入校验perif.identifier,必须将IUO cbPerifList展开为数组。

在“多语句”关闭中

_ = cbPerifList.map { (perif) -> Void in
    print(perif.identifier)
    print("HELLO")
}

编译器不会尝试从上下文中推断闭包类型。因此,cbPerifList被视为常规可选内容,而map()是上述Optional.map方法。在闭包内部,perif具有未包装的类型[CBPeripheral]。这就是为什么perif.identifier无法编译错误消息的原因

  

类型“ [CBPeripheral]”的值没有成员“标识符”

您可以通过显式类型注释“帮助”编译器

_ = cbPerifList.map { (perif: CBPeripheral) -> Void in
    print(perif.identifier)
    print("HELLO")
}

但是-正如已经说过的-在这种特殊情况下,有更好的解决方案。

答案 1 :(得分:2)

map在Swift(和其他地方)中的工作方式是可以将输入从一种类型映射(改变)到另一种类型。因此,根据您的情况,您将在map上调用[CBPeripheral],对于每个元素,map函数将返回另一个值。因此,如果identifierString,则最终将得到一个字符串数组。

这就是它的工作方式。

但是:)

在您的情况下,您已经定义了映射功能,

(perif) -> Void

这意味着您将遍历数组并调用map,并且该函数不会返回任何内容。这意味着结果将是一个填充有Void值的数组。

因此,正如其他人在评论中所建议的那样,如果您只想检查cbPerifList的内容,则最好像这样使用for in循环

for cbPerif in cbPerifList {
    print(cbPerif.identifier)
}

但是,如果您有兴趣获取CBPeripherals的名称数组,则可以执行以下操作

let names = cbPerifList.map { $0.identifier }

对以上内容的评论:要详细了解我们如何才能最终完成编写{ $0.name },请查看Swift文档中有关Closuresthis answer的章节

希望对您有帮助。