默认情况下,如何在Swift中将成员初始化器公开?


164

我有一个定义结构的快速框架:

public struct CollectionTO {
    var index: Order
    var title: String
    var description: String
}

但是,我似乎无法从导入该库的另一个项目中使用隐式成员明智的初始化程序。错误是“ CollectionTO”无法初始化,因为它没有可访问的初始化程序。也就是说,它没有为默认的隐式成员明智的初始化程序提供public关键字。

var collection1 = CollectionTO(index: 1, title: "New Releases", description: "All the new releases")

我必须像这样添加自己的初始化方法:

public struct CollectionTO {
    var index: Order
    var title: String
    var description: String

    public init(index: Order, title: String, description: String) {
        self.index = index;
        self.title = title;
        self.description = description;
    }

}

...但是我宁愿不知道是否还有其他人知道的方法?

Answers:


268

引用手册:

“结构类型的默认成员式初始化程序如果结构的任何存储属性是私有的,则将结构类型的默认成员式初始化程序视为私有。否则,该初始化程序具有内部访问级别。

与上面的默认初始值设定项一样,如果要在一个公共结构类型在另一个模块中使用时使用成员方式初始值设定项来初始化,则必须自己提供一个公共成员方式初始值设定项作为类型定义的一部分。”

摘自“雨燕程序设计语言”,部分“访问控制”


288
好吧,这很烦人。:(
Dan Loewenherz

7
[ github.com/apple/swift-evolution/blob/master/proposals/…说:“引用Chris Lattner:Swift的默认成员级初始化行为至少具有以下缺陷(IMO):2)访问控制+成员级init经常需要您自己实施”。因此,也许这只是一种没有特别原因而存在的缺陷。找不到关于此的更多参考。
2016年

8
@DanLoewenherz是的,这很不方便。理由是:“公共类型默认具有内部成员,而不是公共成员。如果要让类型成员公开,则必须明确地将其标记为公共成员。这项要求确保您可以选择发布某个类型的面向公众的API,并避免错误地将类型的内部工作方式展示为公共API。” 摘录自:苹果公司“ The Swift Programming Language”。iBooks。itun.es/gb/jEUH0.l
bandejapaisa

18
编译器指令最好覆盖默认行为,并将其公开。
bandejapaisa

9
对于默认值imo,内部是一个糟糕的选择。基本上,可以保证您在首次外部引用模块时都会遇到意外问题。为什么不将所有内容都默认为私有,以便我们可以在某些内容未获得正确访问级别的情况下立即告诉我们,然后决定是公共内容还是内部内容?
devios1

72

虽然不可能至少具有默认的成员初始化器,但您可以通过以下步骤快速进行初始化:

  1. 暂时将对象设为类而不是结构
  2. 保存
  3. 右键单击类名称,然后选择“重构”->“生成成员明智的初始化程序”
  4. 将其更改回结构

辉煌。不能感谢您解决这个迅速的不足
Anton Tropashko

1
起作用并且还激发了实际使用类而不是结构的作用youtube.com/watch?v=_V2sBURgUBI
Isaac Carol Weisberg

那是一个超级技巧!
Peymankh

6
从Xcode 11开始,您也可以在结构上使用Generate Memberwise Initializer!
Brock Batsell

太棒了!!! 这不是正确的答案,但这是一个很好的提示!对我有很大帮助!
GuiOS


1

现在,我们有了一个ruby gem💎,可以逐行分析完整的swift数据模型文件,并将public访问修饰符,明智的public成员默认初始化程序和其他内容添加到单独的自动生成的输出swift文件中。

这个宝石叫做swift_republic

请查看以下文档以运行此gem:

https://github.com/mehul90/swift_republic


1
很棒的解决方案!!我已经为它创建了一个包装器,swift_republic并且工作正常。
沙赫德·侯赛因
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.