【发布时间】:2019-09-09 08:38:30
【问题描述】:
我正在使用 Swift 5 和 Vapor 3 制作服务器。在设置路由时,我想从我的控制器调用一个函数,该函数返回一个可选值,如下所示:
//Person.swift
struct Person: Content {
...
}
//PersonController.swift
func update(_ request: Request) throws -> Future<Person> {
let uuid = try request.parameters.next(UUID.self)
return try request.content.decode(Person.self).flatMap { content in
request.withPooledConnection(to: DatabaseIdentifier<PostgreSQLDatabase>.psql) { connection in
/*
* No code completion beyond this point,
* even connection appears as type '_' instead of
* PostgreSQLConnection (not relevant to the question tho,
* just worth noting)
*/
if content.lastName != nil {
return connection.raw("Very long SQL query...")
.binds([...])
.first(decoding: Person.self)
}
return connection.raw("Other long SQL query")
.binds([...])
.first(decoding: Person.self)
}
}
}
router.put("people", UUID.parameter, use: personController.update)
然后我得到这个错误
Cannot convert value of type '(Request) throws -> EventLoopFuture<Person?>' to expected argument type '(Request) throws -> _'
在使用 Vapor 时,我看到很多情况,其中 Xcode 放弃了自动完成功能,所有内容都输入为 _。主要在用作回调的闭包内部。这很烦人,坦率地说,我不确定它是由 Vapor、Swift 还是 Xcode 引起的。这是一个巨大的 PITA,但一旦我编译,一切都会得到解决,类型会被整理出来。但是在这种情况下,它只是不起作用。
所以问题是:当Request.put(_:use:) 的实际定义需要(Request) throws -> T 时,为什么Xcode 会说预期的类型是(Request) throws -> _,这对T 和Future<Person> 和@ 有何区别? 987654331@?
【问题讨论】:
-
您能否在您的
router中显示您的EventLoopFuture类和put函数 -
@AdrianBobrowski 嗯不知道你在问什么,我猜
put函数是指personController.update的内容,EventLoopFuture类是指Person类(实际上是是一个结构)。是这样吗? -
如果
EventLoopFuture<T>与Future<T>兼容,那么您就有问题了,因为在您的情况下,您对T使用了不同的类型。在EventLoopFuture中,您使用Optional<Person>,在Future中,您使用Person。 -
我有点明白,但
Future不仅仅是EventLoopFuture的别名 -
@AdrianBobrowski 我更新了问题以包含
update函数(由Router.put调用)的内容,我认为这就是您所指的。
标签: swift xcode generics vapor server-side-swift