web-dev-qa-db-ja.com

コンパイラーの「内部」保護レベルのため、フレームワークinitのパブリック構造体にアクセスできません

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

2回目の試行:

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

ヒントをいただければ幸いです!

11
Qiquan Lu

教訓:すべてのパブリック構造体にはパブリック初期化が必要です

それは正確ではありません。 ドキュメント は次のように述べています。

構造型のデフォルトのメンバーごとの初期化子

構造体に格納されているプロパティのいずれかがプライベートである場合、構造体タイプのデフォルトのメンバーごとの初期化子はプライベートと見なされます。同様に、構造体に保存されているプロパティのいずれかがファイルプライベートである場合、初期化子はファイルプライベートです。それ以外の場合、初期化子のアクセスレベルは内部です。

そのため、組み込みメンバーワイズ初期化子はパッケージ内でのみ使用できます。パブリック初期化子を提供しない場合、宇宙から構造体を作成することはできません。

16
Andreas Oetjen

すべてのコメントをありがとう、私はついにそれが私にエラーを与えている理由を理解しました。私の2つの試みはどちらも問題ないはずです。

そして、それはこの構造体が問題を引き起こしていないことが判明しました

他の構造体でこの構造体を使用し、パブリックとしてマークします。たとえば、

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

私が投稿したコードには何も問題がなかったため、私の元の投稿はあまり良くありませんでしたが、この投稿を削除しないことにしました。将来、私のような初心者に役立つかもしれません

学習したレッスン:すべてのパブリック構造体にはパブリック初期化が必要です

1
Qiquan Lu

別のフレームワークで構造体にアクセスしようとしている場合、**

構造体内のすべての変数はパブリックである必要があり、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)}

0
ravi shankar