web-dev-qa-db-fra.com

structure publique dans le framework init est inaccessible en raison du niveau de protection «interne» dans le compilateur

J'ai une structure dans un framework appelé "MyFramework"

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

Puis quand j'essaye de créer un ShipmentPackage dans un autre projet/framework

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

J'ai reçu un message d'erreur L'initialiseur "ShipmentPackage" est inaccessible en raison du niveau de protection "interne" Je viens sur ce lien https://forums.Swift.org/t/public-struct-init-is-unexpectedly-internal/5028

J'ai essayé de changer mon code en suivant:

1ère tentative:

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

2e tentative:

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

J'ai également essayé de changer le package_code et le poids en public, mais rien de ce qui précède ne fonctionne, j'ai reçu des messages d'erreur lors de la compilation

<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

Tout indice serait apprécié!

11
Qiquan Lu

Leçon apprise : toutes les structures publiques ont besoin d'un init public

Ce n'est pas tout à fait exact. documentation indique:

Initialiseurs Memberwise par défaut pour les types de structure

L'initialiseur membre par défaut pour un type de structure est considéré comme privé si l'une des propriétés stockées de la structure est privée. De même, si l'une des propriétés stockées de la structure est privée de fichier, l'initialiseur est privé de fichier. Sinon, l'initialiseur a un niveau d'accès interne.

Ainsi, l'initialiseur de membre intégré n'est disponible que dans le package. Si vous ne fournissez pas d'initialiseur public, vous ne pourrez pas créer votre structure à partir de l'espace.

16
Andreas Oetjen

Merci pour tous les commentaires, j'ai finalement compris pourquoi cela me donnait une erreur. Mes deux tentatives devraient bien se passer.

Et il s'est avéré que cette structure ne causait pas de problèmes

J'ai d'autres struct utiliser cette struct et marqué public, par exemple

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

il manquait l'initialiseur, mais pour une raison quelconque, XCode n'indiquera pas l'erreur pour mon espace de travail, mais donnera une erreur au moment de la compilation.

après avoir donné un initialiseur à toutes les structures publiques, l'application passe le compilateur.

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

Mon message d'origine n'était pas vraiment bon, car il n'y avait rien de mal avec le code que j'ai publié, mais décidez de ne pas supprimer ce message, cela pourrait aider les débutants comme moi à l'avenir

Leçon apprise: toutes les structures publiques ont besoin d'une init publique

1
Qiquan Lu

Lorsque vous essayez d'accéder à une structure dans un cadre différent, **

toutes les variables dans la structure doivent être publiques et doivent avoir une valeur par défaut définie dans l'init

**

par exemple:

structure publique LocationPoint {emplacement de la variable publique: NSNumber couleur de la variable publique: 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)
    }
}

Vous pouvez également écrire l'init comme ci-dessous selon la façon dont vous appelez la structure.

public init () {self.location = 0 self.color = UIColor.init (rouge: 255.0/255.0, vert: 1.0, bleu: 205/255.0, alpha: 1)}

0
ravi shankar