2

我正在使用 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,但一旦我编译,一切都会得到解决,类型会被整理出来。但是在这种情况下,它只是不起作用。

所以问题是:为什么 Xcode 会说预期的类型是(Request) throws -> _当实际定义Request.put(_:use:)需要 a时(Request) throws -> T,这如何在TbeFuture<Person>和之间产生差异Future<Person?>

4

1 回答 1

2

.first您在这里调用的方法:

return connection.raw("Other long SQL query")
.binds([...])
.first(decoding: Person.self)

返回Future<Optional<Person>>, 或Future<Person?>. 您路由处理程序的返回类型为Future<Person>,因此您的返回类型不正确。但即使您确实更改了处理程序的返回类型,也无法解决问题。

您的主要问题是您不能从路由处理程序返回可选的,因为绝不会Optional符合ResponseEncodable. 如果您愿意,您可以自己添加一致性。

如果您不想添加一致性,您可以.unwrap(or:)在解码查询结果后使用该方法:

return connection.raw("Other long SQL query")
.binds([...])
.first(decoding: Person.self)
.unwrap(or: Abort(.notFound))

这将检查将来的值是否存在。如果是,则传递该值。否则,未来链会收到您传入的错误,并将其返回。

于 2019-04-19T15:48:19.130 回答