由于编译器具有“内部”保护级别,因此无法访问框架init中的公共结构

Qiq*_* Lu 4 access-control swift swift-custom-framework

我在名为“ MyFramework”的框架中有一个结构

public struct ShipmentPackage:Encodable {
  let package_code:String
  let weight:Float
}
Run Code Online (Sandbox Code Playgroud)

然后,当我尝试在另一个项目/框架中创建ShipmentPackage时

import MyFramework
let onePackage = ShipmentPackage(package_code:"BX",weight:100)
Run Code Online (Sandbox Code Playgroud)

我收到一条错误消息,由于“内部”保护级别,无法访问“ ShipmentPackage”初始化程序。我进入此链接https://forums.swift.org/t/public-struct-init-is-un-expectedly-internal/5028

我试图将代码更改为以下内容:

第一次尝试:

public struct ShipmentPackage:Encodable {
  let package_code:String
  let weight:Float
  public init(package_code:String,weight:Float){
    self.package_code = package_code
    self.weight = weight
  }
}
Run Code Online (Sandbox Code Playgroud)

第二次尝试:

public struct ShipmentPackage:Encodable {
  public let package_code:String
  public let weight:Float
  public init(package_code:String,weight:Float){
    self.package_code = package_code
    self.weight = weight
  }
}
Run Code Online (Sandbox Code Playgroud)

我也尝试将package_code和weight更改为public,但是以上都不起作用,编译时出现错误消息

<unknown>:0: error: 'init' is inaccessible due to 'internal' protection level
<unknown>:0: note: 'init' declared here
<unknown>:0: error: 'init' is inaccessible due to 'internal' protection level
Run Code Online (Sandbox Code Playgroud)

任何提示将不胜感激!

And*_*jen 6

经验教训:所有公共结构都需要一个公共init

那不是很准确。该文档指出:

结构类型的默认成员级初始化程序

如果结构的任何存储属性均为私有,则该结构类型的默认成员初始化器被视为私有。同样,如果结构的任何存储属性是文件专用的,则初始化程序是文件专用的。否则,初始化程序的访问级别为internal。

因此内置成员初始化器仅在包中可用。如果您不提供公共初始化程序,则将无法从外层空间创建结构。

  • 对于具有数十个具有默认值的结构的库来说,这确实是一个很大的缺点。 (32认同)
  • “来自外太空”给我带来了:)的一天。 (3认同)

Qiq*_* Lu 6

感谢所有评论,我终于弄清楚为什么它给我错误了。我的两次尝试都应该没问题。

事实证明这个结构并没有引起问题

例如,我有其他结构使用此结构并标记为公共

public struct Shipment:Encodable {
  let carrier_code:String
  let packages:[ShipmentPackage]
}
Run Code Online (Sandbox Code Playgroud)

缺少初始化程序,但无论出于何种原因,XCode 都不会指示我的工作区的错误,而是在编译时给出错误。

为所有公共结构提供初始值设定项后,应用程序将通过编译器。

public struct Shipment:Encodable {
  let carrier_code:String
  let packages:[ShipmentPackage]
  public init(carrier_code:String,packages:[ShipmentPackage]){
      self.carrier_code = carrier_code
      self.packages = packages
  }
}
Run Code Online (Sandbox Code Playgroud)

我原来的帖子不太好,因为我发布的代码没有任何问题,但决定不删除这篇文章,它可能会帮助像我这样的新手将来

经验教训:所有公共结构都需要公共初始化