Swift:反斜杠点“\.”代表什么意思?

67

我刚接触后端Swift,想使用Vapor快速启动一个项目…… 我运行了vapor new WebServer --template=auth-template,现在我正在尝试弄清楚像return \.email这样的东西是什么意思。 为了更多的背景信息,我正在查看WebServer > Sources > App > Models > Users.swift:

import Authentication
import FluentSQLite
import Vapor

/// Allows users to be verified by basic / password auth middleware.
extension User: PasswordAuthenticatable {
    /// See `PasswordAuthenticatable`.
    static var usernameKey: WritableKeyPath<User, String> {
        return \.email
    }

// ...
}

这里是User类的定义:

/// A registered user, capable of owning todo items.
final class User: SQLiteModel {
    // {omit extra code} ...

    var email: String

    // {omit extra code} ...

    /// Creates a new `User`.
    init(id: Int? = nil, name: String, email: String, passwordHash: String) {
        // {omit extra code} ...
        self.email = email
        // {omit extra code} ...
    }
}
这个反斜杠点符号的表示方法是什么意思?
2个回答

56

简而言之:我们查看了Swift语言参考文档,确实,这个反斜杠点符号的用法被称为key-path-expression

(到此为止,问题已经得到了充分的回答。)

更加实际的方法来获取那个被埋藏的文档:

从你发布的代码中可以看出,User类包含一个名为emailproperty

请注意,假设你正在使用Xcode,如果你将return \.email替换为return \,你会得到编译错误"Expected expression path in Swift key path",所以这是一个提示,这个反斜杠点符号可能与一些称为key path的东西有关。

从key-path文档中,我们可以看到我们也可以写成\User.email(你可以在Xcode中尝试它,没有编译器错误)。

理解代码中正在发生的更大背景:

因此,从语义上理解您正在查看的usernameKey声明的含义,我们可能希望了解WritableKeyPath是什么。简单来说,从文档中可以看出,WritableKeyPath是:“支持从结果值读取和写入的关键路径。”

因此,我们可以看到usernameKey声明接受一个WritableKeyPath对象,并返回一个String,即User.email

此外,显然,User类需要这个usernameKey属性才能符合PasswordAuthenticatable协议,该协议在第一行使用import Authentication导入(如果您想要探索,请查看Dependencies > Auth 2.0.0 > Authentication > Basic > BasicAuthenticatable.swift)。


17
具体而言,使用 \.property 只是 \Type.property 的简写。Swift 通常可以推断出您正在使用的根类型,但有时确实需要完整地键入关键路径。 - Caleb Kleveter
2
@AndreasZUERCHER 接受自己的答案不会增加您的声望等级。如果您回答自己的问题,只有其他人点赞了您的答案,您才能从中获益。 - Caleb Kleveter
4
@AndreasZUERCHER https://stackoverflow.com/help/self-answer - Caleb Kleveter
5
是的,我自问自答。当时我也真的很想知道这个问题的答案,但是在网上找不到太多信息,所以我决定发布一个问答,方便那些喜欢使用StackOverflow回答的人能够轻松找到答案。@AndreasZUERCHER 如果你能提供更好的答案,请随意回答;对于那些对这个问题感兴趣的人来说,这可能是一种有用的替代视角。 - user3773048
1
好的,我会的。我正在考虑还能加些什么。@user3773048,你的回答非常好,就它所说的而言。我会想出一条与你的平行飞行路径,使它们相互补充。 - Andreas ZUERCHER
显示剩余3条评论

-1

[Swift键值编码(KVC)]

这个语法(\<path_to_type_property>)用于指定KeyPath,并允许在编译时检查此路径(Objective-C使用字符串来指定它)。

我们可以从中获得什么:

//`WritableKeyPath` allows in addition to read also write to this property 
//Value Path is User.email
//Root Type is User
//Value Type is String as a result of .email 
var usernameKey: WritableKeyPath<User, String> = \.email
//or
var usernameKey: WritableKeyPath<User, String> = \User.email

如何使用它呢:
//read
let userEmail = someUser[keyPath: usernameKey]

//write
someUser[keyPath: usernameKey] = "foo@gmail.com"

为什么在两个问题上发布相同的基本答案?为什么不投票将一个问题标记为另一个问题的重复呢? - HangarRash

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接