#Swift Property wrappers separation for code and action

在 Swift 中,Property Wrappers 是一种强大的特性,允许我们为属性附加额外的行为逻辑,从而简化代码、提高代码的可重用性。它们是一个通过封装属性的读写逻辑来提供行为扩展的机制。

Property Wrappers 的工作原理

Property Wrapper 本质上是一个包含 wrappedValue 属性的结构体或类。通过在属性前加上 @ 符号,我们可以将一个 Property Wrapper 应用到该属性上。Swift 会将该属性的存取逻辑委托给 Property Wrapper 的 wrappedValue 属性。

创建一个 Property Wrapper

一个简单的 Property Wrapper 示例:

swift 复制代码
@propertyWrapper
struct Clamped {
    private var value: Int
    private let range: ClosedRange<Int>

    var wrappedValue: Int {
        get { value }
        set { value = min(max(newValue, range.lowerBound), range.upperBound) }
    }

    init(wrappedValue: Int, _ range: ClosedRange<Int>) {
        self.range = range
        self.value = min(max(wrappedValue, range.lowerBound), range.upperBound)
    }
}

在这个例子中,Clamped 是一个 Property Wrapper,它限制整数值在一个给定范围内。当值超出范围时,它会自动调整到范围边界。

使用 Property Wrapper

在定义属性时应用 Property Wrapper,如下所示:

swift 复制代码
struct Settings {
    @Clamped(0...10) var volume: Int = 5
}

在这个示例中,当你设置 volume 的值时,它会自动调整在 0 到 10 的范围内:

swift 复制代码
var settings = Settings()
settings.volume = 15  // volume 会被限制为 10
print(settings.volume)  // 输出: 10

Property Wrappers 的好处

  • 代码复用:可以将属性的常见行为封装在 Property Wrapper 中,减少重复代码。
  • 数据验证:可以在写入属性时自动执行验证逻辑,比如上面的范围限制。
  • 数据转换:可以在读写属性时自动执行转换逻辑,例如自动加密/解密。

更高级的用法:Projected Value

Property Wrappers 还可以定义一个 projectedValue,它提供额外的接口或信息给属性。例如,可以使用 $ 符号访问 projectedValue:

swift 复制代码
@propertyWrapper
struct Uppercase {
    private var value: String = ""

    var wrappedValue: String {
        get { value }
        set { value = newValue.uppercased() }
    }

    var projectedValue: String {
        return "Projected value: \(value)"
    }
}

struct Text {
    @Uppercase var name: String
}

var text = Text()
text.name = "hello"
print(text.name)         // 输出: HELLO
print(text.$name)        // 输出: Projected value: HELLO

在这个例子中,$name 会返回 projectedValue,提供额外的信息或接口。

总结

Property Wrappers 是一个极其有用的 Swift 特性,它允许开发者将属性的读写逻辑封装在一个独立的、可重用的组件中。它不仅简化了代码,还提供了一种优雅的方法来应用属性行为逻辑。

相关推荐
白帽攻防录5 小时前
SRC 挖洞:PostScript 打印机驱动双 RCE,打印服务器怎么变成内网跳板
开发语言·网络安全·php·内网安全
十年Java程序媛5 小时前
Java枚举Enum完整教程|替代静态常量,开发与面试要点
java·开发语言·spring boot·后端·面试
2603_965148116 小时前
电商选品调研:通过关键词搜索API获取市场热销商品,结合商品详情API分析竞品卖点与定价
开发语言·数据库·人工智能·python·信息可视化
xixiaoyunya7 小时前
Python 异步编程入门:用 asyncio 轻松实现并发任务
开发语言·python·php
学逆向的7 小时前
C 循环结构的执行效率分析
c语言·开发语言·数据结构·网络安全
小坏讲微服务7 小时前
刚发布一个月的JDK 27,为什么我建议你立刻升级?
java·开发语言·spring boot·spring·架构·求职招聘·springboot4
打工仔折腾 AI9 小时前
用 Dashlet 把极空间 NAS 服务入口整理成统一导航首页的实践
java·开发语言·人工智能·后端·python·rpc·ai agent 实战
MATLAB代码顾问9 小时前
Simulink PI 参数扫描与批量仿真完整 MATLAB 代码
开发语言·matlab
Want5959 小时前
Python跳动的爱心②
开发语言·python·数学建模
小羊没烦恼!10 小时前
T-SQL查询进阶--理解SQL SERVER中的分区表
服务器·开发语言·前端·javascript·html