You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中遵循含属性要求的协议是否无需显式定义getter与setter?

嘿,这俩问题问到点子上了,正好是Swift协议属性里很容易混淆的点,我给你掰扯清楚:

问题1:在Swift中,创建遵循要求getter和setter的协议的类时,是否无需显式写getter和setter?

完全不需要!Swift里的存储属性(用var声明的那种)本身就自带可读可写的能力,这是它的默认特性。当协议要求某个属性是{ get set }时,你只需要在类/结构体里声明一个普通的var存储属性,就自动满足协议的要求了——因为存储属性天生就有get和set的功能,根本不用你手动写get {}或者set {}的代码块。

举个实际的例子:

// 定义要求可读可写属性的协议
protocol UserProtocol {
    var name: String { get set }
    var age: Int { get set }
}

// 遵循协议的类,直接声明存储属性即可
class User: UserProtocol {
    var name: String
    var age: Int
    
    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }
}

你看,这个User类里的name和age都没写get/set,但编译器完全认可它符合UserProtocol的要求,不会报错。

问题2:未为age定义get/set结构、未为name定义get结构,是不是因为协议里{ get set }的属性仅要求可读可写,存储属性就能满足?

没错,就是这个逻辑!协议里的{ get set }本质是在能力层面做约束:这个属性必须支持读取(get)和修改(set)操作。而Swift的var存储属性天生就具备这两个能力,所以根本不需要额外写getter或setter的实现代码。

反过来想,如果协议要求的是{ get }(只读),那你可以用let常量存储属性,也可以用var存储属性,甚至可以用只写getter的计算属性。但如果是{ get set },就必须用var存储属性,或者是同时实现get和set的计算属性——不过存储属性是最直接省事的方式,因为它默认就达标了。

顺便补个小细节:如果是用计算属性来满足{ get set }的要求,那你才需要显式写get和set的代码块,比如:

class User: UserProtocol {
    // 私有存储属性做底层存储
    private var _name: String
    // 计算属性显式实现get和set
    var name: String {
        get { return _name }
        set { _name = newValue }
    }
    // 存储属性依然不用写get/set
    var age: Int = 0
    
    init(name: String) {
        self._name = name
    }
}

这里的name是计算属性,所以必须显式写get和set才能满足协议,但age作为存储属性还是啥都不用加。


内容的提问来源于stack exchange,提问作者JonEF

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 07:17:17