如果没有更多的上下文,表达式的类型是模棱两可的

我得到了一个“ 如果没有更多的上下文,表达式的类型是不明确的”的这部分代码从一个项目,我试图升级到最新的斯威夫特版本。我好像想不通。我尝试了不同的方法,但不能让它工作。

问题在于这一行的语法

let imageToDeleteParameters  = imagesToDelete.map { ["id": $0.id, "url": $0.url.absoluteString, "_destroy": true] }

完整代码:

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 }
]
}
}
267914 次浏览

编译器无法确定生成 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]

这是一个结构的工作,它将极大地简化使用这个数据结构的工作。

显式地声明映射函数的输入应该可以做到这一点:

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

在那个代码片段中用“ $0”的实际类替换“ WhateverClass”,它应该可以工作。

当函数的参数名称错误时就会发生这种情况。

例如:

functionWithArguments(argumentNameWrong: , argumentName2: )

你声明你的职能是:

functionWithArguments(argumentName1: , argumentName2: ){}

这通常发生在更改变量名时。请确保在更改变量名时进行重构。

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

对我来说,当我试图在一个数组上使用 for (index, object)循环而不添加 .enumerated()部分时,我得到了这个 Swift 错误..。

在调用函数时,当我在参数中的逗号前放置一个空格时,我得到了这个错误。

我用:

myfunction(parameter1: parameter1 , parameter2: parameter2)

然而,它本应该是:

myfunction(parameter1: parameter1, parameter2: parameter2)

删除空格消除了错误消息

当函数参数的类型不匹配时,我收到了这条消息。在我的例子中,它是一个 String 而不是一个 URL。

在我的例子中,当我没有向构造函数添加可选属性时,会显示这个错误消息。

struct Event: Identifiable, Codable {


var id: String
var summary: String
var description: String?
// also has other props...


init(id: String, summary: String, description: String?){
self.id = id
self.summary = summary
self.description = description
}
}


// skip pass description
// It show message "Type of expression is ambiguous without more context"
Event(
id: "1",
summary: "summary",
)


// pass description explicity pass nil to description
Event(
id: "1",
summary: "summary",
description: nil
)


但它看起来总是没有发生。

我在我的游乐场测试这个代码,它显示警告更具体

var str = "Hello, playground"
struct User {
var id: String
var name: String?
init(id: String, name: String?) {
self.id = id
self.name = name
}
}


User(id: "hoge") // Missing argument for parameter 'name' in call

=之前有两个 " "

let imageToDeleteParameters = imagesToDelete.map { ["id": $0.id, "url": $0.url.absoluteString, "_destroy": true] }

在我的案例中,这种情况发生在 NSFetcheResultsController 上,原因是我为不同的模型定义了 NSFetcheResultsController,而不是创建了初始化请求(RemotePlaylist vs Playlist) :

  var fetchedPlaylistsController:NSFetchedResultsController<RemotePlaylist>!

但是他们要求另一个播放列表:

let request = Playlist.createFetchRequest()
fetchedPlaylistsController = NSFetchedResultsController(fetchRequest: request, ...

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

下面是一个故障排除检查清单,请确认:

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

策略

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

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

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

此时,您可能已经实现了这一点,例如,您原以为想要分配的属性实际上有一个属性,该属性具有您想要传递的实际值,而不是这个属性。

对我来说,这种情况是类型推断 我已经从 int To float 改变了函数参数,但是没有更新调用代码,编译器也没有警告我传递给函数的错误类型

之前

func myFunc(param:Int, parma2:Int) {}

之后

func myFunc(param:Float, parma2:Float) {}

调用错误代码

var param1:Int16 = 1
var param2:Int16 = 2
myFunc(param:param1, parma2:param2)// error here: Type of expression is ambiguous without more context

修正:

var param1:Float = 1.0f
var param2:Float = 2.0f
myFunc(param:param1, parma2:param2)// ok!

作为 the Eye 的回答,它不是 这个问题的答案,但是我也来这里寻找我的案例中的错误,因为其他人可能会发现这也很有用:

当我试图计算两种不同类型的值时出错了,我得到了这个错误消息。

在我的例子中,我试图将 CGFloat除以 Double

在我的例子中,我在创建发行版本时遇到了这个错误,而且一个类只引用了 Debug 上下文方法。

尝试为分发版本编译下面的类。

class MyClass {
func sayHello() {
helloWorld()
}
    

#if DEBUG
func helloWorld() {
print("Hello world")
}
#endif
}

在我的例子中,我传递的参数具有可选的 String值。提供一个默认值(如果该值是 nil)为我解决了这个问题。

我改了这个

router?.pushToDetailsScreen(
gitHubRepositoryOwnerName: gitHubRepositoryDetails?[index].owner?.login,
gitHubRepositoryName: gitHubRepositoryDetails?[index].name,
avatarUrl: gitHubRepositoryDetails?[index].owner?.avatar_url)

到这里

router?.pushToDetailsScreen(
gitHubRepositoryOwnerName: gitHubRepositoryDetails?[index].owner?.login ?? "",
gitHubRepositoryName: gitHubRepositoryDetails?[index].name ?? "",
avatarUrl: gitHubRepositoryDetails?[index].owner?.avatar_url ?? "")

确保如果有任何委托方法可用于扩展名,然后实现这些方法,错误将消失。

我的问题是没有默认值的参数

我变了

let contaPadrao = RedeConta(agencia: cPadrao?.agencia,
conta: cPadrao?.conta,
dac: cPadrao?.dac)

let contaPadrao = RedeConta(agencia: cPadrao?.agencia ?? "",
conta: cPadrao?.conta ?? "",
dac: cPadrao?.dac ?? "")

由于多种原因,可能会显示此错误。最突出的原因之一是类型不匹配。比如说,

假设,参数图标是一种数组类型,我们传递了一个 Enum 作为 IconDismiss。

## Wrong
text.config = TextField.Config(isClearable: true, icons: IconDismiss)
## Correct
text.config = TextField.Config(isClearable: true, icons: [IconDismiss])

在我的案例中,它与@scottyBlades 所说的非常相似。我更改了一个成员变量名,但没有在回调中更新它,这导致了令人困惑/无益的错误。

class SomeClass {
var newVarName: String


func doSomething() {
Async.makeCall { result in // << error shows here
self.oldVarName = result // not changing it to newVarName was the cause
}
}
}