Swift中能否重写嵌套结构体/扩展内结构体的计算属性?
问题:重写嵌套结构体中的计算属性
现有如下Swift代码,其中嵌套结构体Foo.FooContent包含计算属性b,逻辑为self.a + 1:
public struct Foo { var c: Int init(c: Int) { self.c = c } // 假设此处有大量实现代码 } extension Foo { struct FooContent { var a: Int public var b: Int { self.a + 1 } init(a: Int) { self.a = a } } // 假设此处有大量实现代码 } var obj = Foo.FooContent(a: 1) print(obj.b) // 输出2
希望在不改动Foo或FooContent原有代码的前提下,将b的逻辑改为self.a + 2,但直接扩展尝试重写会编译失败:
extension Foo.FooContent { public var b: Int { self.a + 2 } // 编译错误:b已被定义 }
可行方案
Swift中结构体是值类型,不支持继承重写,且扩展不能重复定义已有成员,这是语言设计的规则(并非缺陷)——值类型强调值语义的一致性,重写会破坏这种一致性。以下是几种替代方案:
1. 创建包装结构体(推荐)
定义一个新结构体,持有原FooContent实例,代理其所有原有属性,并重新实现b的逻辑:
struct ModifiedFooContent { private var content: Foo.FooContent // 代理原有的a属性 var a: Int { get { content.a } set { content.a = newValue } } // 重写b的计算逻辑 var b: Int { content.a + 2 } // 初始化方法 init(a: Int) { self.content = Foo.FooContent(a: a) } // 如果需要原实例的其他方法/属性,可继续添加代理 } // 使用示例 var modifiedObj = ModifiedFooContent(a: 1) print(modifiedObj.b) // 输出3 modifiedObj.a = 5 print(modifiedObj.b) // 输出7
这种方式完全保留原类型的功能,同时实现了自定义的b逻辑,且无需修改原有代码。
2. 新增替代属性
如果可以接受使用新的属性名,直接在扩展中添加一个新的计算属性:
extension Foo.FooContent { public var modifiedB: Int { self.a + 2 } } // 使用示例 var obj = Foo.FooContent(a: 1) print(obj.modifiedB) // 输出3
这种方式最简单,但需要在所有使用的地方替换属性名。
3. 修改原类型为类(仅限可修改原代码场景)
如果有权限修改原代码,可以将FooContent改为类,因为类支持继承和重写:
// 修改原扩展中的FooContent为类 extension Foo { class FooContent { var a: Int public var b: Int { self.a + 1 } init(a: Int) { self.a = a } } } // 子类重写b属性 class ModifiedFooContent: Foo.FooContent { override var b: Int { self.a + 2 } } // 使用示例 var obj = ModifiedFooContent(a: 1) print(obj.b) // 输出3
但此方案需要改动原有代码,不符合“不改动原功能”的前提,仅作为备选。
内容的提问来源于stack exchange,提问作者Murd
相关产品推荐
相关产品推荐

