默认情况下,如何将成员初始化程序公开,用于 Swift 中的结构?

Posted

技术标签:

【中文标题】默认情况下,如何将成员初始化程序公开,用于 Swift 中的结构?【英文标题】:How can I make the memberwise initialiser public, by default, for structs in Swift? 【发布时间】:2014-12-01 05:05:42 【问题描述】:

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

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")

我必须像这样添加自己的 init 方法:

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;
    


...但如果有其他人知道的方法,我宁愿不要?

【问题讨论】:

【参考方案1】:

引用手册:

"结构类型的默认成员初始化器 如果结构的任何存储属性是私有的,则结构类型的默认成员初始化器被认为是私有的。否则,初始化程序的访问级别为 internal。

与上面的默认初始化程序一样,如果您希望公共结构类型在用于另一个模块时可以使用成员初始化程序进行初始化,您必须自己提供一个公共成员初始化程序作为类型定义的一部分。"

摘自"The Swift Programming Language",部分"Access Control"。

【讨论】:

嗯,这很烦人。 :( [github.com/apple/swift-evolution/blob/master/proposals/… 说:“引用 Chris Lattner 的话:Swift 的默认成员初始化行为至少存在以下缺陷(IMO):2)访问控制 + 成员初始化通常需要您自己实现”。所以也许这只是一个没有特别原因的缺陷。找不到更多关于此的参考资料。 @DanLoewenherz 是的,这很不方便。理由是:“公共类型默认具有内部成员,而不是公共成员。如果您希望类型成员是公共的,则必须明确将其标记为公共的。此要求可确保您选择发布的类型的面向公众的 API,并避免错误地将类型的内部工作方式呈现为公共 API。”摘自:Apple Inc.“Swift 编程语言”。电子书。 itun.es/gb/jEUH0.l 编译器指令可以很好地覆盖默认行为,并将其公开。 Internal 对于默认值 imo 来说是一个糟糕的选择。它基本上保证了你第一次在外部引用模块时会遇到意想不到的问题。为什么不将所有内容都默认为私有,这样我们就可以立即知道什么时候没有正确的访问级别,然后决定它应该是公共的还是内部的?【参考方案2】:

我们现在有一个 ruby​​ gem ? 可以逐行解析完整的 swift 数据模型文件,并将公共访问修饰符、公共成员默认初始化器和其他内容添加到单独的自动生成的输出 swift 文件中.

这个宝石叫做swift_republic

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

https://github.com/mehul90/swift_republic

【讨论】:

很棒的解决方案!我已经为swift_republic 创建了一个包装器并且工作正常。【参考方案3】:

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

更新:Xcode 11 及更高版本

正如 Brock Batsell 在 cmets 中提到的,对于 Xcode 11 及更高版本,您只需要这样做:

右键单击类或结构名称并选择重构-> 生成成员初始化器

Xcode 10 及更早版本的答案

    将对象暂时设为类而不是结构 保存 右键单击类名并选择重构-> 生成成员初始化器 改回结构体

【讨论】:

太棒了。非常感谢您解决这个快速的缺陷 工作并且也激励实际使用类而不是结构youtube.com/watch?v=_V2sBURgUBI 这是一个超级技巧! 从 Xcode 11 开始,您也可以在结构上使用 Generate Memberwise Initializer! 太棒了!!!这不是正确的答案,但是一个非常好的提示!帮了我很多!

以上是关于默认情况下,如何将成员初始化程序公开,用于 Swift 中的结构?的主要内容,如果未能解决你的问题,请参考以下文章

成员初始化列表的使用及特点

无法在属性初始化程序中使用实例成员,将变量设置为惰性不起作用

默认情况下,不要使用Spring Data Rest和Jpa公开Entity类中的字段

ReadOnlyCollection 或 IEnumerable 用于公开成员集合?

私有变量

GitLab:部分公共项目