getter & setter & private 关键字 & 计算属性 & 懒加载

本文介绍了Swift语言中的Person类实现,包括属性的声明与访问、只读属性与计算型属性的定义方式,以及懒加载的使用场景。通过具体的代码示例展示了Swift中不同属性类型的特点及其应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 新建 Person.swift 类对象

class Person: NSObject {
    // -- getter & setter 方法在 Swift 中极少用,仅供参考
    // OC 中利用 getter 方法,编写懒加载,而 Swift 中提供了 lazy

   //如果不希望暴露的方法或者属性,都要用 private 保护起来
   private var _name: String?
    
    var name: String?{
        get{
            //返回 _成员变量 的值
            return _name;
        }
        set{
            // 使用 _成员变量记录新的数值
            _name = newValue;
        }
    }
    
    var name2: String?
}

2. 调用函数

func demo(){
        let p = Person()
        
        p.name = "zhangsan"
        print(p.name)
        
        p.name2 = "xiao xiao"
        print(p.name2)
    }

3. 只读属性:在 Person.swift 中添加

    // 只读属性的简写方法 - 如果属性的‘修饰方法’,只提供 getter,那么 get{} 可以省略
    // 另外一种叫法:‘计算’型属性
    // 每一次调用的时候,都会执行 {} 中的代码,结果取决其他属性或者原因
    // * 每次都要计算,浪费性能 - 如果计算量小,可以使用
    // * 不需要开辟格外的空间
    var title2: String{
        return "Mr title2 " + (name ?? "")
    }

4. 懒加载:在Person.swift 中添加

    //懒加载 - 第一次调用的时候,执行闭包,并且在 title3 中保存闭包的执行结果
    //再次调用,不再执行闭包,而是直接返回之前计算的结果
    // * 只需要计算一次
    // * 需要开辟单独的空间保存计算结果
    // * 闭包的代码,再也不会被调用
    // * 如果计算量很大,需要提前准备
    lazy var title3: String? = {
        //闭包: 是一个提前准备好的代码,在需要的时候执行
        //使用 self,用于闭包在执行时,准备的绑定对象
        //闭包中的 self. 可写可不写 self.name
        return "Mr title3 " + (name ?? "")
    }()

5. 调用函数

 func demo(){
        let p = Person()
        p.name = "zhangsan"
        print(p.name)
        //p.name2 = "xiao xiao"
        //print(p.name2)
        print(p.title)
        //计算型属性
        print(p.title2)
        //懒加载
        print(p.title3)
        print("-------")
        p.name = "lisi"
        p.name = nil
        p.name = "xiao xiao"
        print(p.title2)
        print(p.title3)
         //在 Swift 开发中,有多时候编译器反应迟钝,可以 cmd + b
        //p.title2 = "title 22"
    }
<think>我们正在讨论TypeScript中的gettersetter。在给定的代码中,`VibrateEnabled`是一个属性,它通过get和set来定义访问和修改行为。 作用: 1. getter(get): 当读取属性时调用的函数。它用于获取属性的值,在这里返回私有静态变量`vibrateEnabled`的值。 2. setter(set): 当设置属性值时调用的函数。它用于设置私有静态变量`vibrateEnabled`的值,并且在此过程中还可以执行其他操作(比如将设置保存到本地存储)。 具体到这段代码: - 当外部代码读取`Setting.VibrateEnabled`时,会调用get方法,返回当前的震动开关状态(`this.vibrateEnabled`)。 - 当外部代码设置`Setting.VibrateEnabled = someValue`时,会调用set方法,将`someValue`赋值给`this.vibrateEnabled`,并且调用`StorageUtil.setItem`将设置保存到本地存储。 这样设计的好处: 1. 封装:外部代码不能直接修改私有变量`vibrateEnabled`,必须通过setter,这样可以在设置时加入额外的逻辑(如持久化)。 2. 控制:在setter中可以添加验证逻辑(虽然这里没有,但可以扩展),比如只允许布尔值。 3. 便捷:从外部使用起来就像访问普通属性一样,但背后有逻辑执行。 示例: ```typescript // 读取震动开关状态 let isVibrateEnabled = Setting.VibrateEnabled; // 调用getter // 设置震动开关状态 Setting.VibrateEnabled = false; // 调用setter,同时会保存到本地存储 ``` 如果没有setter,直接公开变量,那么每次修改时都需要手动调用保存方法,容易遗漏。使用setter可以确保每次修改都自动保存。 类似地,其他两个属性(`SfxEnabled`和`BgmEnabled`)也是同样的原理。 因此,gettersetter在这里的作用是提供对私有变量的受控访问,并在设置时自动持久化。 下面,我将按照要求提出相关问题。</think>在 TypeScript 中,`get` 和 `set` 是访问器属性(accessor properties)的关键字,它们提供了对类成员更精细的控制。在你的代码中: ### `get` 的作用:读取属性值 ```typescript public static get VibrateEnabled(): boolean { return this.vibrateEnabled } ``` 1. **定义属性访问器**: - `get` 定义了一个获取属性值的方法 - 当访问 `Setting.VibrateEnabled` 时,会自动调用此方法 2. **行为特征**: - 只读访问:外部代码可以读取值但不能直接修改 - 计算属性:可以在返回值前执行计算逻辑 - 封装实现:隐藏内部存储细节 3. **使用示例**: ```typescript // 读取震动开关状态 const isVibrateOn = Setting.VibrateEnabled; if (isVibrateOn) { // 执行震动效果 device.vibrate(); } ``` ### `set` 的作用:设置属性值 ```typescript public static set VibrateEnabled(v: boolean) { this.vibrateEnabled = v StorageUtil.setItem('vibrateEnabled', v) } ``` 1. **定义属性设置器**: - `set` 定义了一个设置属性值的方法 - 当赋值 `Setting.VibrateEnabled = value` 时,会自动调用此方法 2. **行为特征**: - 值验证:可以添加验证逻辑(如检查数据类型) - 副作用操作:设置值时可触发其他操作(如保存到本地存储) - 写保护:控制如何修改内部状态 3. **使用示例**: ```typescript // 玩家在设置界面关闭震动 Setting.VibrateEnabled = false; // 等价于执行: // Setting.vibrateEnabled = false; // StorageUtil.setItem('vibrateEnabled', false); ``` ### getter/setter 与普通方法的区别 | 特性 | getter/setter | 普通方法 | |------|---------------|----------| | 语法 | `obj.property` | `obj.method()` | | 使用方式 | 像访问属性一样使用 | 需要显式调用 | | 逻辑封装 | 隐藏实现细节 | 暴露实现细节 | | 副作用 | 可在setter中执行 | 需手动调用 | | 类型安全 | 强类型检查 | 参数类型检查 | ### 实际应用场景 1. **数据验证**: ```typescript private static _volume: number = 50; public static get volume(): number { return this._volume; } public static set volume(value: number) { // 确保音量在0-100范围内 if (value >= 0 && value <= 100) { this._volume = value; StorageUtil.setItem('volume', value); } else { console.error("Invalid volume value"); } } ``` 2. **延迟加载**: ```typescript private static _config: GameConfig | null = null; public static get config(): GameConfig { if (!this._config) { this._config = this.loadConfig(); } return this._config; } ``` 3. **计算属性**: ```typescript private static _score: number = 0; private static _multiplier: number = 1; public static get totalScore(): number { return this._score * this._multiplier; } ``` ### 最佳实践建议 1. **保持getter轻量**:避免在getter中执行耗时操作 2. **setter中的验证**:始终验证输入值 3. **避免副作用**:getter不应修改状态 4. **命名约定**:使用描述性名称(如 `isEnabled` 而非 `flag`) 5. **与React/Vue集成**:访问器属性可以无缝接入响应式框架 在你的代码中,使用getter/setter的主要优势是: 1. 封装了内部状态 `vibrateEnabled` 2. 自动将设置保存到本地存储 3. 提供更自然的API(`Setting.VibrateEnabled` 而非 `Setting.getVibrateEnabled()`) 4. 保持代码简洁易读 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hanyang Li

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值