155 votes

Comment utilisez-vous les espaces de noms dans Swift ?

La documentation ne mentionne que les types imbriqués, mais il n’est pas clair s’ils peuvent être utilisés comme espaces de noms. Je n’ai pas trouvé tout exprès d’espaces de noms.

157voto

matt Points 60113

Je décrirais Swift namespacing comme ambitieux; qu'il a été donné beaucoup de publicité qui ne correspond pas à tout sens de la réalité sur le terrain.

Par exemple, la WWDC vidéos état que si un cadre, vous êtes l'importateur dispose d'une classe MyClass et votre code a une classe Maclasse, ces noms ne sont pas en conflit parce que "name mangling" leur donne différents noms internes. En réalité, cependant, ils ne le conflit, dans le sens que votre propre code de MyClass gagne, et vous ne pouvez pas spécifier "non, Non, je veux dire la MyClass dans le cadre" - disant TheFramework.MyClass ne fonctionne pas (le compilateur sait ce que tu veux dire, mais il dit qu'il ne peut pas trouver une telle classe dans le cadre).

Mon expérience est que Swift n'est donc pas d'espace de noms dans le moindre. En tournant une de mes applications, Objective-C, Swift, j'ai créé un cadre intégré parce que c'était tellement facile et cool à faire. L'importation le cadre, toutefois, les importations de tous les Swift trucs dans le-cadre - de sorte presto, une fois de plus, il y a juste un espace de noms et il est mondial. Et il n'y a pas de Swift en-têtes de sorte que vous ne pouvez pas cacher de tous les noms.

EDIT: En de la graine 3, cette fonctionnalité est désormais de mettre en ligne, dans le sens suivant: si votre code principal contient MyClass et votre cadre MyFramework contient MyClass, l'ancien éclipse celui-ci par défaut, mais vous pouvez rejoindre l'un dans le cadre à l'aide de la syntaxe MyFramework.MyClass. Ainsi, nous avons effectivement les rudiments d'un espace de noms distinct!

EDIT 2: En de la graine 4, nous avons maintenant des contrôles d'accès! De Plus, dans une de mes applications, j'ai un cadre intégré et bien sûr, tout était caché par défaut et j'ai eu à exposer tous les bits de l'API publique de manière explicite. C'est une grande amélioration.

119voto

Eonil Points 19404

Répondu par SevenTenEleven dans le dev Apple forum:

Les espaces de noms ne sont pas de fichier par fichier; ils sont par-cible (basé sur le "Produit Nom du Module" paramètre de construction). Donc, si vous voulez quelque chose de comme ceci: importation FrameworkA importation FrameworkB

FrameworkA.foo() Tous les Swift déclarations sont considérées comme faisant partie de certains module, de sorte que même lorsque vous dites "NSLog" (oui, ça existe encore) vous obtenez ce que Swift pense que "de la Fondation.NSLog".

Aussi Chris Lattner est pépiement à propos de l'espace de noms.

Namespacing est implicite dans swift, toutes les classes (etc) sont implicitement portée par le module (Xcode cible), ils sont en. pas de préfixes de classe besoin

Semble être très différent de ce que j'ai pensé.

20voto

bWlrYWphdWhvbmVu Points 381

Tout en faisant quelques essais avec ce que j'avais fini la création de ces "espaces" classes dans leurs propres fichiers par extension de la racine "package". Vous ne savez pas si cela va à l'encontre des pratiques exemplaires ou si elle a des répercussions je suis mot conscience(?)

AppDelegate.swift

var n1 = PackageOne.Class(name: "Package 1 class")
var n2 = PackageTwo.Class(name: "Package 2 class")

println("Name 1: \(n1.name)")
println("Name 2: \(n2.name)")

PackageOne.swift

import Foundation

struct PackageOne {
}

PackageTwo.swift

import Foundation

struct PackageTwo {
}

PackageOneClass.swift

extension PackageOne {
    class Class {
        var name: String
        init(name:String) {
            self.name = name
        }
    }
}

PackageTwoClass.swift

extension PackageTwo {
    class Class {
        var name: String
        init(name:String) {
            self.name = name
        }
    }
}

Edit:

Viens de découvrir que la création de "modules" dans le code ci-dessus ne fonctionnent pas si vous utilisez des fichiers séparés. Peut-être que quelqu'un peut soupçon sur pourquoi ce serait le cas?

L'ajout de fichiers suivants:

PackageOneSubPackage.swift

import Foundation

extension PackageOne {
    struct SubPackage {
    }
}

PackageOneSubPackageClass.swift

extension PackageOne.SubPackage {
    class Class {
        var name: String
        init(name:String) {
            self.name = name
        }
    }
}

Son lancement une erreur de compilateur: 'Sous-paquetage' n'est pas un type de membre de "PackageOne'

Si je déplace le code de PackageOneSubPackageClass.swift à PackageOneSubPackage.swift il fonctionne. N'importe qui?

Edit 2:

Bidouiller avec ce encore et découvert (dans Xcode 6.1 bêta 2) qu'en définissant les paquets dans un fichier, ils peuvent être étendus dans des fichiers séparés:

public struct Package {
  public struct SubPackage {
    public struct SubPackageOne {
    }
    public struct SubPackageTwo {
    }
  }
}

Voici mes fichiers dans un résumé: https://gist.github.com/mikajauhonen/d4b3e517122ad6a132b8

12voto

Kevin Sylvestre Points 15551

Je crois que ceci est réalisé en utilisant :

Ensuite, on peut y accéder en utilisant :

7voto

Ivan Genchev Points 1622

Swift utilise des modules comme en python (voir ici et ici) et comme @Kevin Sylvestre suggéré, vous pouvez également utiliser les types imbriqués comme des espaces de noms.

Et pour étendre la réponse de @Daniel A. Blanc, dans la WWDC ils parlaient des modules en swift.

Aussi ici est expliqué:

Types déduits de rendre le code plus propre et moins sujettes à des erreurs, tandis que les les modules d'éliminer les en-têtes et de fournir des espaces de noms.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X