38

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

public struct ShipmentPackage:Encodable {
  let package_code:String
  let weight:Float
}

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

import MyFramework
let onePackage = ShipmentPackage(package_code:"BX",weight:100)

我收到一条错误消息“ShipmentPackage”初始化程序由于“内部”保护级别而无法访问我来到此链接https://forums.swift.org/t/public-struct-init-is-unexpectedly-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
  }
}

第二次尝试:

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
  }
}

我也尝试将 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

任何提示将不胜感激!

4

4 回答 4

51

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

这并不完全准确。该文档指出:

结构类型的默认成员初始化器

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

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

public struct YourFrameworkStruct {
    let frameworkStructProperty: String!
    /// Your public structs in your framework need a public init.
    /// 
    /// Don't forget to add your let properties initial values too.
    public init(frameworkStructProperty: String) {
        self.frameworkStructProperty = frameworkStructProperty
    }
}
于 2019-02-13T15:10:44.233 回答
5

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

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

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

public struct Shipment:Encodable {
  let carrier_code:String
  let packages:[ShipmentPackage]
}

缺少初始化程序,但无论出于何种原因,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
  }
}

我原来的帖子不是很好,因为我发布的代码没有任何问题,但决定不删除这个帖子,它可能对将来像我这样的新手有所帮助

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

于 2019-02-13T17:00:32.600 回答
1

将您的结构及其属性标记为公共

看起来public init不再需要添加具有所有参数和属性分配的方法。这在Xcode 13 beta 5中对我有用:

public struct ShipmentPackage: Encodable {
  public let package_code: String
  public let weight: Float
}

注意public属性前面的关键字,init结构中没有显式方法。

于 2021-09-08T11:46:48.857 回答
0

当您尝试访问不同框架中的结构时,**

结构中的所有变量都应该是公共的,并且应该在 init 中设置一个默认值

**

例如:

public struct LocationPoint { public var location: NSNumber public var color: UIColor

    public init(location: NSNumber? = 0, color: UIColor? = nil ) {
        self.location = location ?? 0
        self.color = color ?? UIColor.init(red: 255.0/255.0, green: 1.0, blue: 205/255.0, alpha: 1)
    }
}

您还可以根据调用结构的方式编写如下的 init。

 public init() {
     self.location = 0
     self.color = UIColor.init(red: 255.0/255.0, green: 1.0, blue: 205/255.0, alpha: 1)
 }
于 2019-05-25T12:20:02.100 回答