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
}
AI 代码解读

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?>
AI 代码解读

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

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

let stringDebugDescription : KeyPath<String, String> = \.debugDescription
AI 代码解读
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
AI 代码解读

场景描述

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

使用Keypath的好处

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

实际应用

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

struct Movie {
    
   let title: String
   let director: String
   let rating: Double
}
AI 代码解读

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

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),
   // ... 其他电影
]
AI 代码解读

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

let sortedByRating = movies.sorted(by: \.rating)
AI 代码解读

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

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

let sortedByTitle = movies.sorted(by: \.title)
let sortedByDirector = movies.sorted(by: \.director)
AI 代码解读

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

我们还有一个特殊的路径,可以引用整个实例而不是属性。我们可以使用以下语法创建一个\.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")
AI 代码解读

总结

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

相关文章
iOS 最完整小说阅读器(Swift-Demo)
iOS 最完整小说阅读器(Swift-Demo)
606 0
uni-vue3-wetrip自创跨三端(H5+小程序+App)酒店预订app系统模板
vue3-uni-wetrip原创基于vite5+vue3+uniapp+pinia2+uni-ui等技术开发的仿去哪儿/携程预约酒店客房app系统。实现首页酒店展示、预订搜索、列表/详情、订单、聊天消息、我的等模块。支持编译H5+小程序+App端。
244 8
快速集成 Flutter Shorebird 热更新
Flutter Shorebird 是一种云端代码推送服务,可以让开发者在几分钟内集成,无需修改代码即可将更新推送到任何 Dart 代码,支持所有 Android 和 iOS 设备,并符合 App Store 和 Play Store 的规定。Shorebird 最大的优点是无代码侵入,快速集成,设计优秀。
413 2
快速集成 Flutter Shorebird 热更新
安卓模拟器接口抓包教程
用uni-app开发安卓应用时,查看接口数据不能像在浏览器中可以直接通过network查看,只能借助抓包工具来抓包,还有一些线上应用我们也只能通过抓包来排查具体的问题
使用阿里云OpenAPI的身份证识别Swift SDK时遇到了报错
使用阿里云OpenAPI的身份证识别Swift SDK时遇到了报错
181 3
(七)Open Stack(M)---- Swift安装和配置(下)
(七)Open Stack(M)---- Swift安装和配置(下)
146 0
(七)Open Stack(M)---- Swift安装和配置(上)
(七)Open Stack(M)---- Swift安装和配置(上)
201 0
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等

登录插画

登录以查看您的控制台资源

管理云资源
状态一览
快捷访问