我熟悉Vapor 2.0服务器端Swift框架,让我感到困惑的是字符串文字的广泛使用。例如,实现Model
协议,您必须解析并序列化这样的行(取自自动生成的示例项目):
// Initializes the Post from the database row
init(row: Row) throws {
content = try row.get("content")
}
// Serializes the Post to the database
func makeRow() throws -> Row {
var row = Row()
try row.set("content", content)
return row
}
正如您所看到的,对于每个属性,您只使用其数据库名称作为此特定协议的字符串文字。在其他情况下还有更多 - 例如,Database
协议,您自己的方法等。
在这里使用文字字符串作为参数具有明显的缺点,即静态分析器不检查它们(就像Objective-C中的键值参数一样),使得这种方法非常容易出错。我有什么最佳实践吗?
答案 0 :(得分:1)
您可以通过将其作为静态属性存储在模型上并引用它来轻松地最小化重复字符串的次数。
final class Post: Model {
// Keys
static let contentKey = "content"
// Properties
var content: String
// Initializes the Post from the database row
init(row: Row) throws {
content = try row.get(Post.contentKey)
}
// Serializes the Post to the database
func makeRow() throws -> Row {
var row = Row()
try row.set(Post.contentKey, content)
return row
}
...
}
extension Post: Preparation {
static func prepare(_ database: Database) throws {
try database.create(self) { builder in
builder.id()
builder.string(Post.contentKey)
}
}
...
}
不幸的是,为了使事情变得更加类型安全,你可能会做出有意义的事情。目前无法向编译器提供有关数据库的实际结构(或任何其他字符串,如JSON)的信息。如果我们能做到这一点真的很棒!也许有一天。
(我会考虑更新API和网站模板以包含此内容,在此处跟踪问题:https://github.com/vapor/api-template/issues/35)
答案 1 :(得分:0)
都能跟得上!你正确地做对了。由于Swift中缺少高级运行时库,我们无法做到这一点。
但是,在Swift 4中,您可以将键路径用于相同目的。
\Post.content
将为内容变量创建一个静态检查的密钥路径。
关键路径上的WWDC会议绝对值得关注。