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

Swift中为何不能为结构体使用open关键字?求专家解答附示例

Swift中open/public关键字的适用范围说明

核心结论

  • open 修饰符仅适用于类,它是专门为类的跨模块继承、重写场景设计的权限控制符。
  • public 可用于类、结构体、枚举、协议等类型,但针对类和结构体的作用有本质差异:
    • 对类而言,public 允许跨模块访问,但限制跨模块继承;
    • 对结构体(值类型)而言,public 仅表示允许跨模块访问,不存在继承相关的权限控制(因为结构体本身不支持继承)。

具体示例

1. 正确使用 open 类(支持跨模块继承)

// 模块A中定义
open class Animal {
    var name: String
    var age: Int
    
    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }
    
    open func makeSound() {
        print("Some sound")
    }
}

在其他模块(比如模块B)中,可直接继承这个open类并重写它的open方法:

// 模块B中使用
class Dog: Animal {
    override func makeSound() {
        print("Woof!")
    }
}

2. public 类(仅允许跨模块访问,不能跨模块继承)

// 模块A中定义
public class Car {
    var brand: String
    
    init(brand: String) {
        self.brand = brand
    }
}

在模块B中,能创建Car的实例,但无法继承它:

// 模块B中使用
let myCar = Car(brand: "Toyota") // 合法
// class ElectricCar: Car {} // 编译报错:无法继承跨模块的public类

3. public 结构体(仅支持跨模块访问)

结构体可以使用public,但不能用open(结构体不支持继承,open的设计无意义):

// 模块A中定义
public struct Person {
    public var name: String
    public var age: Int
    
    public init(name: String, age: Int) {
        self.name = name
        self.age = age
    }
}

在模块B中可正常访问和实例化:

// 模块B中使用
let person = Person(name: "Alice", age: 25)
print(person.name) // 输出 "Alice"

4. 错误示例:结构体使用open

尝试给结构体加open会直接编译报错:

// 编译报错:'open' modifier cannot be applied to a struct
open struct Book {
    var title: String
}

设计逻辑说明

Swift的访问控制是基于模块和继承场景设计的:

  • 类是引用类型,支持继承,因此需要open和public两个权限来区分「允许跨模块继承」和「仅允许跨模块访问」;
  • 结构体、枚举是值类型,不支持继承,因此不需要open这种针对继承的修饰符,只用public控制访问权限就足够了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 18:32:28