Swift 中的 KeyPath

简介: Swift 中的 反斜杠点 (\.xxx)到底是个啥

Swift 中的 KeyPath

当在Swift中进行编程时,Keypath(键路径)是一个强大的特性,用于引用对象的属性,从而实现更加灵活和类型安全的代码。让我们通过一个实际案例详细解析Keypath的使用。

// 1
struct User {
    
   let name: String
   let email: String
   let address: Address?
   let role: Role
}

// 2
struct Address {
    
   let street: String
}

// 3
enum Role {
    
   case admin
   case member
   case guest

   var permissions: [Permission] {
    
       switch self {
    
       case .admin:
           return [.create, .read, .update, .delete]
       case .member:
           return [.create, .read]
       case .guest:
           return [.read]
       }
   }
}

// 4
enum Permission {
    
   case create
   case read
   case update
   case delete
}

KeyPath 表达式 \typeName.path

// 1
let stringDebugDescription = \String.debugDescription 
// KeyPath

// 2
let userRole = \User.role 
// KeyPath

// 3
let firstIndexInteger = \[Int][0] 
// WritableKeyPath<[Int], Int>

// 4
let firstInteger = \Array<Int>.first 
// KeyPath<[Int], Int?>

与 Swift 中的大多数内容一样,在可以推断类型的上下文中可以省略类型名称。

在下面的示例中,类型名称可以从显式变量类型推断出来,因此我们可以将类型名称留空。请注意,我们仍然需要\.

let stringDebugDescription : KeyPath<String, String> = \.debugDescription
keyPath 访问值
var user = User(
   name: "Sarunw",
   email: "sarunw@example.com",
   address: nil,
   role: .admin)

let userRoleKeyPath = \User.role
//  WritableKeyPath<User, Role>

// 1
let role = user[keyPath: userRoleKeyPath]
print(role) // admin

// 2
user[keyPath: userRoleKeyPath] = .guest

print(user.role) // guest

场景描述

假设我们正在开发一个电影信息的应用,我们有一个Movie结构体表示电影的信息,其中包括标题、导演、评分等属性。我们希望在用户界面中显示电影信息,同时支持根据电影的不同属性进行排序。

使用Keypath的好处

使用Keypath,我们可以在运行时指定需要排序的属性,同时保持类型安全,避免了硬编码字符串。这样,我们可以在代码中更方便地使用各种属性进行排序,而无需手动编写每个属性的比较函数。

实际应用

首先,我们定义一个Movie结构体:

struct Movie {
    
   let title: String
   let director: String
   let rating: Double
}

然后,我们创建一个包含电影信息的数组:

let movies = [
   Movie(title: "Inception", director: "Christopher Nolan", rating: 8.8),
   Movie(title: "The Dark Knight", director: "Christopher Nolan", rating: 9.0),
   Movie(title: "Interstellar", director: "Christopher Nolan", rating: 8.6),
   // ... 其他电影
]

现在,假设我们希望按照电影的评分进行排序。我们可以使用Keypath来实现这个需求:

let sortedByRating = movies.sorted(by: \.rating)

上述代码中,\.rating表示一个Keypath,它引用了Movie结构体的rating属性。我们将这个Keypath传递给sorted(by:)方法,这样就可以按照评分对电影数组进行排序了。

我们还可以进一步扩展,按照不同的属性进行排序:

let sortedByTitle = movies.sorted(by: \.title)
let sortedByDirector = movies.sorted(by: \.director)

这样,我们可以灵活地在不同场景下按照不同属性对电影数组进行排序,而无需编写多个比较函数或者使用字符串进行硬编码。

我们还有一个特殊的路径,可以引用整个实例而不是属性。我们可以使用以下语法创建一个\.self

var foo = "Foo"
// 1
let stringIdentity = \String.self
//  WritableKeyPath<String, String>

foo[keyPath: stringIdentity] = "Bar"
print(foo) // Bar

struct User {
    
 let name: String
}
var user = User(name: "John")
// 2
let userIdentity = \User.self
// WritableKeyPath<User, User>

user[keyPath: userIdentity] = User(name: "Doe")
print(user) // User(name: "Doe")

总结

Keypath是Swift中一个强大的特性,可以让我们更方便地引用和操作对象的属性,同时保持类型安全。在实际开发中,Keypath可以用于各种场景,包括排序、KVO(键值观察)等。通过上述案例,我们看到了如何在一个电影信息应用中使用Keypath来灵活地进行属性排序。

相关文章
|
安全 JavaScript Java
iOS使用PushKit实现VoIP
iOS使用PushKit实现VoIP
1801 0
|
机器学习/深度学习 人工智能 自然语言处理
深度学习中的迁移学习:从理论到实践
科技进步不断推动人工智能的发展,其中深度学习已成为最炙手可热的领域。然而,训练深度学习模型通常需要大量的数据和计算资源,这对于许多实际应用来说是一个显著的障碍。迁移学习作为一种有效的方法,通过利用已有模型在新任务上的再训练,大大减少了数据和计算资源的需求。本文将详细探讨迁移学习的理论基础、各种实现方法以及其在实际应用中的优势和挑战。
|
1月前
|
自然语言处理 前端开发 数据挖掘
最新版通义千问(Qwen3.8-Max-Preview)功能介绍
通义千问Qwen3.8-Max-Preview是通义千问团队推出的旗舰级大模型预览版,以2.4万亿参数规模、第三代MoE混合专家架构为核心,实现了原生多模态处理、百万级超长上下文、双推理模式、全栈代码工程、多智能体协作等突破性能力,在复杂推理、专业开发、长文档处理、多模态融合等场景实现跨越式升级,成为面向企业级与开发者的高性能基座模型。本文将从核心架构、基础能力、专业场景功能、技术优势、接入配置与实战应用等维度,全面解析Qwen3.8-Max-Preview的完整功能体系,帮助用户快速掌握其核心价值与使用方法。
353 2
|
2月前
|
数据采集 自然语言处理 监控
终于有人讲清楚:主数据、元数据、参考数据到底是什么了!
企业数据混乱常源于三类基础数据未统一:主数据(管“是谁/是什么”,如客户、商品)、元数据(管“数据怎么理解/从哪来”,如字段定义、指标口径)、参考数据(管“按何标准分类”,如币种、订单状态)。三者协同,方能实现数据“找得到、看得懂、对得上、追得回、用得准”。(239字)
|
2月前
|
人工智能 缓存 IDE
Gemini CLI 免费配额缩减后的 6 种有效应对方案(2026)
2026 年 6 月 18 日,Gemini CLI 停止为免费的『用 Google 账号登录』通道处理请求,AI Pro 和 Ultra 登录也一并停掉。这个二进制没死:它仍是 Apache-2.0,仍在维护(v0.49.0),配上 API key 照样能跑。如果你正盯着『This client is no longer supported for Gemini Code Assist for individuals』发愁,那是认证问题,不是装坏了。修法就是别再用 Google 账号登录,改用一个开通了计费的 API key。2026 年 9 月还有第二堵墙等着你,届时不受限的 Standa
|
5月前
|
监控 NoSQL 数据挖掘
金融科技反洗钱中,IP查询工具能帮我们追踪资金流向吗?
本文分享IP数据在反洗钱中的实战应用:通过IP归属地、网络类型(net_type)、风险分(risk_score)、威胁标签(threat_tags)等字段,与交易数据关联,构建“账户-IP-行为”图谱,有效识别地理异常、代理/IP匿名操作、团伙聚类及跨境合规风险,显著提升可疑交易识别精准度。
金融科技反洗钱中,IP查询工具能帮我们追踪资金流向吗?
|
存储 关系型数据库 MySQL
PostgreSQL + Apache Doris:构建用于实时分析的 HTAP 架构
本文介绍如何通过 PostgreSQL + Apache Doris 构建 HTAP 架构:PostgreSQL 专注高并发事务,Doris 承担实时分析。借助 CDC 实时同步、MOW 引擎秒级更新、向量化查询与分层存储,实现事务/分析物理隔离、查询提速数倍、成本显著降低。
296 1
|
10月前
|
云安全 人工智能 自然语言处理
产业升级丨负责任的 AI,从 AI 治理和安全能力构建开始
未来,在 AI 与人类和谐共生的世界里,AI 不仅是强大的工具,更是负责任的伙伴。
|
6月前
|
机器学习/深度学习 自然语言处理 搜索推荐
你的模型真的“懂”吗?用 Captum / SHAP 把神经网络扒开给你看
你的模型真的“懂”吗?用 Captum / SHAP 把神经网络扒开给你看
600 4
|
6月前
|
缓存 监控 算法
详细介绍一下淘宝商品详情API接口系列的调用频率限制
淘宝商品详情 API 系列(核心为taobao.item.get)的调用频率限制,采用应用级 QPS + 分钟级 + 日总量三重管控,按开发者身份、应用类型、接口版本、套餐等级分级执行,是平台保障服务稳定性、防滥用的核心机制。以下从限制规则、限流机制、超限处理、提额申请、调用方控频方案五方面详细说明。