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

问题描述 投票:0回答:2

我是后端 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} ...
    }
}

这个反斜杠点符号是什么意思?

swift authentication vapor
2个回答
56
投票

tl;dr: 我们看一下 Swift 语言参考,果然,这种反斜杠点表示法的用法被称为 key-path-expression

(至此,问题已经得到充分解答。)

关于如何获取该隐藏文档的更实际的方法:

从您发布的代码中可以看到,User 类包含一个名为 email

property

请注意,假设您使用的是 Xcode,如果您将

return \.email
替换为
return \
,则会收到编译错误
"Expected expression path in Swift key path"
,因此这暗示该反斜杠点符号可能与称为一条关键路径。

从有关 key-path 的文档中,我们看到我们也可以编写

\User.email
(您可以在 Xcode 中尝试,不会出现编译器错误)。

了解代码中发生的事情的更大背景:

因此,从语义上讲,要理解您正在查看的

usernameKey
声明的含义,我们可能需要了解
WritableKeyPath
是什么。简单来说,从文档中,我们看到
WritableKeyPath
是:“支持读取和写入结果值的关键路径。”

因此,我们看到

usernameKey
声明接受一个
WritableKeyPath
对象并返回一个
String
,即
User.email

此外,很明显,User 类需要这个

usernameKey
属性才能符合
PasswordAuthenticatable
协议,该协议是在第一行使用
import Authentication
导入的(如果您想探索那里,请查看 依赖项> Auth 2.0.0 > 身份验证 > 基本 > BasicAuthenticatable.swift)。


0
投票

[Swift 键值编码(KVC)]

此语法(

\<path_to_type_property>
)用于指定
KeyPath
并允许在编译时检查此路径(Objective-C使用String来指定它)。

我们可以从中得到什么:

//`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] = "[email protected]"
© www.soinside.com 2019 - 2024. All rights reserved.