如果没有更多的上下文Swift,表达式的类型是不明确的

Flo*_*DAL 28 swift swift3

我正在尝试升级到最新的Swift版本的项目代码的这部分代码中得到一个' 表达式类型没有更多上下文 '.我似乎无法弄明白.我尝试过不同的东西,却无法让它发挥作用.

问题出在这条线的语法上

let imageToDeleteParameters  = imagesToDelete.map { ["id": $0.id, "url": $0.url.absoluteString, "_destroy": true] }
Run Code Online (Sandbox Code Playgroud)

完整代码:

extension TutorialCreationRequest: WebserviceParametrable {
    func toParameters() -> [String: AnyObject] {
        let imageParameters = images.map { ["url": $0] }
        let imageToDeleteParameters  = imagesToDelete.map { ["id": $0.id, "url": $0.url.absoluteString, "_destroy": true] }
        return [
            "title": title,
            "is_draft": isDraft,
            "difficulty": difficulty,
            "duration": duration,
            "cost": cost,
            "user_id": userId,
            "description": description,
            "to_sell": toSell,
            "images": [imageParameters, imageToDeleteParameters].flatMap { $0 }
        ]
    }
}
Run Code Online (Sandbox Code Playgroud)

Sco*_*des 49

如果突出显示的方法或属性的任何部分试图访问类型不正确的属性或方法,就会发生这种情况。

这是故障排除清单,请确保:

  • 调用站点和实现中的参数类型匹配。
  • 参数名称在调用站点和实现中匹配。
  • 方法名称在调用站点和实现中匹配。
  • 在使用和实施的属性或方法匹配的返回值(即:enumerated()
  • 您没有具有可能不明确的类型(例如协议或泛型)的重复方法。
  • 使用类型推断时,编译器可以推断出正确的类型。

策略

  • 尝试将您的方法分解为更多更简单的方法/实现。

例如,假设您compactMap在一组自定义类型上运行。在传递给compactMap方法的闭包中,您初始化并返回另一个自定义结构。当您收到此错误时,很难判断代码的哪一部分有问题。

  • 出于调试目的,您可以使用for in循环而不是compactMap.
  • 您可以将它们分配给 for 循环中的常量,而不是直接传递参数。

此时,您可能会意识到,例如,您认为要分配的属性实际上有一个属性,该属性具有您想要传递的实际值。

  • Swift 会在“方法的完全不相关的部分”报告错误,甚至不会在错误消息中暗示它可能出现在方法的任何部分,这是非常不直观的。而且,方法中也没有提示问题出在哪里,迫使我们盲目地去寻找解决方案。至少知道编译器可以做到这一点会有所帮助。 (7认同)
  • 讽刺的是“如果没有更多的上下文,错误是不明确的。” 只是开玩笑。我认为共同点是类型不匹配。如果存在类型不匹配,则代码的两部分将不同步。编译器如何知道您决定哪一个是正确的?也就是说,它可能有一些逻辑来计算一致的类型用法,然后突出显示与最低数量的常见类型不匹配的情况。 (4认同)
  • 或者突出显示两者并告诉我它对它们的类​​型了解多少?任何事情都会比我们目前收到的完全不透明的错误消息更好。 (3认同)

The*_*Eye 24

不是这个问题的答案,但是当我来到这里寻找错误时,其他人可能会发现这也很有用:

对我来说,当我尝试for (index, object)在阵列上使用循环而不添加.enumerated()部件时,我得到了这个Swift错误...


Dan*_*das 12

如果您的参数名称错误,则会发生这种情况.

例:

functionWithArguments(argumentNameWrong: , argumentName2: )
Run Code Online (Sandbox Code Playgroud)

并且您将您的功能声明为:

functionWithArguments(argumentName1: , argumentName2: ){}
Run Code Online (Sandbox Code Playgroud)

当您更改变量的名称时,通常会发生这种情况.确保在执行此操作时重构.

  • 对我来说,这是返回类型问题。 (3认同)

Ale*_*ica 11

编译器无法确定使用Dictionary的类型,因为它不是同源的.您有不同类型的值.解决这个问题的唯一方法就是把它变成一个[String: Any],这将使一切变得笨拙.

return [
    "title": title,
    "is_draft": isDraft,
    "difficulty": difficulty,
    "duration": duration,
    "cost": cost,
    "user_id": userId,
    "description": description,
    "to_sell": toSell,
    "images": [imageParameters, imageToDeleteParameters].flatMap { $0 }
] as [String: Any]
Run Code Online (Sandbox Code Playgroud)

这是结构的工作.它将大大简化这种数据结构的使用.


bra*_*ray 10

当函数参数的类型不合适时,我收到了这条消息。在我的情况下,它是一个字符串而不是一个 URL。


Jer*_*urr 6

显式声明该映射函数的输入应该可以解决问题:

let imageToDeleteParameters  = imagesToDelete.map {
    (whatever : WhateverClass) -> Dictionary<String, Any> in
    ["id": whatever.id, "url": whatever.url.absoluteString, "_destroy": true]
}
Run Code Online (Sandbox Code Playgroud)

将该代码片段中的“WhateverClass”替换为“$0”的真实类,它应该可以工作。


nar*_*rco 5

当我在调用函数时在参数中的逗号前放置一个空格时出现此错误。

例如,我用过:

myfunction(parameter1: parameter1 , parameter2: parameter2)
Run Code Online (Sandbox Code Playgroud)

而它应该是:

myfunction(parameter1: parameter1, parameter2: parameter2)
Run Code Online (Sandbox Code Playgroud)

删除空间摆脱了错误信息