A documentação menciona apenas tipos aninhados, mas não está claro se eles podem ser usados como espaços para nome. Não encontrei nenhuma menção explícita a namespaces.
Uma rápida pesquisa com Ctrl-F no iBook deles não mostra instâncias de namespaces ... então vou com não?
Justin Niessner
1
Não sei por que essa pergunta está encerrada. Vi namespace no keynote no lado esquerdo do ícone da Swift, e eu ainda não consigo encontrar qualquer menção a partir da documentação ...
eonil
Não consegui encontrar nenhuma informação sobre isso, o Google me levou a esta pergunta :). Talvez uma das sessões da WWDC possa lançar um pouco mais de luz sobre isso.
Zyphrax
Também estou esperando alguém na WWDC apresentar uma boa explicação.
eonil
A resposta de Eonil está correta. Você usa módulos no Xcode para separar suas classes.
Os espaços para nome não são por arquivo; eles são por destino (com base na configuração de criação "Nome do módulo do produto"). Então você terminaria com algo assim:
importFrameworkAimportFrameworkBFrameworkA.foo()
Todas as declarações do Swift são consideradas parte de algum módulo; portanto, mesmo quando você diz " NSLog" (sim, ele ainda existe), você está obtendo o que o Swift considera " Foundation.NSLog".
O espaço para nome está implícito no Swift, todas as classes (etc) têm o escopo implicitamente definido pelo módulo (destino do Xcode) em que estão. Nenhum prefixo de classe é necessário
Fóruns do Apple Dev ... Eu já vi tantas ervas daninhas que você não acreditaria!
Nicolas Miari 06/04
1
O link para os fóruns de desenvolvedores da Apple agora está quebrado e forums.developer.apple.com, infelizmente , a Apple não importou esse segmento para o novo site de fóruns.
Dai
2
@Dai Parece que é por isso que devemos evitar os fóruns da Apple para perguntas e respostas ... Mas os membros principais da equipe de desenvolvimento parecem não se importar muito com SO. Que tragédia.
eonil
1
o que você quer dizer com tumbleweed?
21818 Alexander Mills
148
Eu descreveria o namespace de Swift como aspiracional; recebeu muita publicidade que não corresponde a nenhuma realidade significativa no terreno.
Por exemplo, os vídeos da WWDC afirmam que, se uma estrutura que você está importando tem uma classe MyClass e seu código tem uma classe MyClass, esses nomes não entram em conflito porque "mangling de nome" fornece nomes internos diferentes. Na realidade, no entanto, eles fazem conflito, no sentido de que vitórias MyClass seu próprio código, e você não pode especificar "Não, não, eu quero dizer a MyClass no quadro" - dizendo TheFramework.MyClassnão funciona (o compilador sabe o que quer dizer , mas diz que não consegue encontrar essa classe na estrutura).
Minha experiência é que Swift, portanto, não é um espaço de nome nem um pouco. Ao transformar um dos meus aplicativos do Objective-C para o Swift, criei uma estrutura incorporada porque era muito fácil e legal de fazer. A importação da estrutura, no entanto, importa todo o material Swift na estrutura - então, presto, mais uma vez, existe apenas um espaço para nome e é global. E não há cabeçalhos Swift, portanto você não pode ocultar nenhum nome.
EDIT: Na semente 3, esse recurso está começando a ficar online, no seguinte sentido: se seu código principal contiver MyClass e sua estrutura MyFramework contiver MyClass, a primeira ofusca a última por padrão, mas você pode alcançá-la na estrutura usando a sintaxe MyFramework.MyClass. Assim, temos de fato os rudimentos de um espaço de nome distinto!
EDIT 2: Na semente 4, agora temos controles de acesso! Além disso, em um dos meus aplicativos eu tenho uma estrutura incorporada e, com certeza, tudo estava oculto por padrão e eu tive que expor explicitamente todos os bits da API pública. Esta é uma grande melhoria.
Obrigado por esta resposta. Funciona não apenas com Frameworks, mas também com a Biblioteca Padrão. Você pode "substituir" a matriz, por exemplo. Em seguida, "Matriz" se refere à sua própria classe Array personalizada, e a Matriz da Biblioteca Padrão está disponível como "Swift.Array".
George
3
@ George E da mesma forma para o NSArray; se você o ofuscar, ainda poderá se referir a ele como Foundation.NSArray.
Matt
1
Portanto, sem ter que examinar a história do pensamento nos espaços para nome nos betas: onde está essa resposta agora?
Dan Rosenstark 26/01
1
@Yar como indicado nas edições. O nome do módulo é um espaço de nomes opcional se houver ambiguidade e agora existe privacidade, portanto os nomes dos módulos ficam ocultos, a menos que expostos e um nome possa ser confinado a um arquivo.
Matt
2
Isso está me incomodando há muito tempo, parece que qualquer projeto Swift não deve usar um prefixo por causa do que a Apple está reivindicando; no entanto, neste momento, ainda é necessário um prefixo, mesmo com os modificadores de acesso. Embora você não entre em conflito com o pacote ou as classes privadas na estrutura da Apple, qualquer coisa declarada pública, por exemplo, String, se você declarar isso novamente, ou qualquer nova classe, ela acabará usando a sua, a menos que você tenha o hábito de referindo-se a todas as classes com seu espaço para nome .... não é bom.
Oscar Gomez
19
Ao fazer algumas experiências com isso, acabei criando essas classes "namespaced" em seus próprios arquivos, estendendo o "pacote" raiz. Não tenho certeza se isso é contra as melhores práticas ou se tem alguma implicação de que estou ciente (())
extensionPackageOne{classClass{var name:Stringinit(name:String){self.name = name
}}}
PackageTwoClass.swift
extensionPackageTwo{classClass{var name:Stringinit(name:String){self.name = name
}}}
Editar:
Acabei de descobrir que a criação de "subpacotes" no código acima não funcionará se você estiver usando arquivos separados. Talvez alguém possa sugerir por que esse seria o caso?
Não sei o que você quer dizer com "teste", mas fui adiante e comecei a criar meu aplicativo usando a técnica acima e parece funcionar até agora com a ressalva que adicionei à minha entrada acima. Estou fazendo isso principalmente porque estou acostumado a organizar meu código dessa maneira em outros idiomas e ficaria grato se alguém com mais conhecimento pudesse me dizer que é uma má idéia até que eu vá longe demais! :)
bWlrYWphdWhvbmVu
1
continue ... é isso que queremos ... ser capaz de ter a mesma classe de nome em dois pacotes diferentes para poder existir e referenciar adequadamente (arquivos mais importantes) e, se não funcionar, o conjunto idéia de namespace é uma idéia fracasso ...
user2727195
Algum efeito colateral usando "struct" como uma maneira de invadir namespaces?
Alex Nolasco
Não que eu tenha encontrado no que diz respeito ao desempenho. O Xcode (6.1 GM) está em alguns casos raros reclamando de tipos que não existem, mas acredito que esse pode ser o caso quando não estiver estruturando um código como esse também. Recentemente, resolvi um problema adicionando ao meu alvo de teste todos os arquivos que não fazem sentido, mas resolveram o problema. :)
Ainda não estou muito feliz com a maneira como os namespaces são feitos ... e se eu tiver dez classes diferentes em um namespace e, além disso, eu preferir manter as classes em seus arquivos individuais, não quero inchar um arquivo / estrutura com todas as classes, sugestões.
precisa saber é o seguinte
2
Eu me pergunto por que eles não pensaram em incluir pacotes, é disso que precisamos, não espaços para nome, quero dizer, olhe para outras linguagens de alto nível como Java, C #, ActionScript, todos eles têm pacotes, espaços para nome nesse contexto não são nada diferentes de usar o NS ou outros prefixos para suas classes de projeto
user2727195 04/04
1
Não posso deixar de pensar se o uso de estruturas como uma maneira de invadir espaços para nome pode causar problemas desconhecidos.
Alex Nolasco
1
Essa é uma boa solução para isso. Tentei usar essa abordagem, mas tive que parar imediatamente. Quando tentei nomear minhas classes relacionadas à exibição de namespace (digamos um CustomTableViewCell), o preenchimento automático no construtor de interface não o sugeriu. Eu precisaria copiar e colar manualmente o nome da classe para a exibição, se eu tivesse usado essa abordagem.
ArG
1
Geralmente você usaria um enum, não um struct, portanto não poderá instanciar um Foo.
Kevin
7
O Swift usa módulos como o python (veja aqui e aqui ) e, como @Kevin Sylvestre sugeriu, você também pode usar os tipos aninhados como namespaces.
E para estender a resposta de Daniel A. White, na WWDC, eles estavam falando sobre os módulos rapidamente.
Estou procurando por pacotes como construct, conforme mencionado no seu segundo link 6.4 Packages (Python), namespaces como tipos aninhados não podem levar muito longe, e se eu tiver 10 classes diferentes e em arquivos diferentes em um namespace ou, digamos, um pacote???
precisa saber é o seguinte
7
Os espaços para nome são úteis quando você precisa definir a classe com o mesmo nome da classe na estrutura existente.
Suponha que seu aplicativo tenha MyAppnome e você precise declarar seu costume UICollectionViewController.
Por quê? . Porque o que você declarou está declarado no módulo atual , que é seu destino atual . E UICollectionViewControllerde UIKité declarado no UIKitmódulo.
Como usá-lo no módulo atual?
var customController =UICollectionViewController()//your custom class
var uikitController =UIKit.UICollectionViewController()//class from UIKit
Como distingui-los de outro módulo?
var customController =MyApp.UICollectionViewController()//your custom class
var uikitController =UIKit.UICollectionViewController()//class from UIKit
Você pode usar extensiona structabordagem mencionada para espaçamento de nomes sem precisar recuar todo o seu código para a direita. Venho brincando um pouco com isso e não tenho certeza se iria criar espaços para nome Controllerse Viewsnomes, como no exemplo abaixo, mas ilustra o quão longe ele pode ir:
Profiles.swift :
// Define the namespaces
structProfiles{structViews{}structViewControllers{}}
Perfis / ViewControllers / Edit.swift
// Define your new class within its namespace
extensionProfiles.ViewControllers{classEdit:UIViewController{}}// Extend your new class to avoid the extra whitespace on the left
extensionProfiles.ViewControllers.Edit{overridefunc viewDidLoad(){// Do some stuff
}}
Perfis / Visualizações / Edit.swift
extensionProfiles.Views{classEdit:UIView{}}extensionProfiles.Views.Edit{overridefunc drawRect(rect:CGRect){// Do some stuff
}}
Não usei isso em um aplicativo, pois ainda não precisava desse nível de separação, mas acho que é uma ideia interessante. Isso elimina a necessidade de sufixos uniformes de classe, como o onipresente * ViewController, que é irritantemente longo.
No entanto, ele não reduz nada quando é referenciado, como em parâmetros de método como este:
Respostas:
Respondida por SevenTenEleven no fórum de desenvolvedores da Apple :
Também Chris Lattner twittou sobre namespacing .
Parece ser muito diferente do que venho pensando.
fonte
forums.developer.apple.com
, infelizmente , a Apple não importou esse segmento para o novo site de fóruns.Eu descreveria o namespace de Swift como aspiracional; recebeu muita publicidade que não corresponde a nenhuma realidade significativa no terreno.
Por exemplo, os vídeos da WWDC afirmam que, se uma estrutura que você está importando tem uma classe MyClass e seu código tem uma classe MyClass, esses nomes não entram em conflito porque "mangling de nome" fornece nomes internos diferentes. Na realidade, no entanto, eles fazem conflito, no sentido de que vitórias MyClass seu próprio código, e você não pode especificar "Não, não, eu quero dizer a MyClass no quadro" - dizendo
TheFramework.MyClass
não funciona (o compilador sabe o que quer dizer , mas diz que não consegue encontrar essa classe na estrutura).Minha experiência é que Swift, portanto, não é um espaço de nome nem um pouco. Ao transformar um dos meus aplicativos do Objective-C para o Swift, criei uma estrutura incorporada porque era muito fácil e legal de fazer. A importação da estrutura, no entanto, importa todo o material Swift na estrutura - então, presto, mais uma vez, existe apenas um espaço para nome e é global. E não há cabeçalhos Swift, portanto você não pode ocultar nenhum nome.
EDIT: Na semente 3, esse recurso está começando a ficar online, no seguinte sentido: se seu código principal contiver MyClass e sua estrutura MyFramework contiver MyClass, a primeira ofusca a última por padrão, mas você pode alcançá-la na estrutura usando a sintaxe
MyFramework.MyClass
. Assim, temos de fato os rudimentos de um espaço de nome distinto!EDIT 2: Na semente 4, agora temos controles de acesso! Além disso, em um dos meus aplicativos eu tenho uma estrutura incorporada e, com certeza, tudo estava oculto por padrão e eu tive que expor explicitamente todos os bits da API pública. Esta é uma grande melhoria.
fonte
Foundation.NSArray
.Ao fazer algumas experiências com isso, acabei criando essas classes "namespaced" em seus próprios arquivos, estendendo o "pacote" raiz. Não tenho certeza se isso é contra as melhores práticas ou se tem alguma implicação de que estou ciente (())
AppDelegate.swift
PackageOne.swift
PackageTwo.swift
PackageOneClass.swift
PackageTwoClass.swift
Editar:
Acabei de descobrir que a criação de "subpacotes" no código acima não funcionará se você estiver usando arquivos separados. Talvez alguém possa sugerir por que esse seria o caso?
Adicionando os seguintes arquivos ao acima:
PackageOneSubPackage.swift
PackageOneSubPackageClass.swift
Está lançando um erro de compilador: 'SubPackage' não é um tipo de membro de 'PackageOne'
Se eu mover o código de PackageOneSubPackageClass.swift para PackageOneSubPackage.swift, ele funcionará. Qualquer um?
Edição 2:
Brincando com isso ainda e descobri (no Xcode 6.1 beta 2) que, ao definir os pacotes em um arquivo, eles podem ser estendidos em arquivos separados:
Aqui estão meus arquivos em um sumário: https://gist.github.com/mikajauhonen/d4b3e517122ad6a132b8
fonte
Acredito que isso seja alcançado usando:
Em seguida, ele pode ser acessado usando:
fonte
enum
, não umstruct
, portanto não poderá instanciar umFoo
.O Swift usa módulos como o python (veja aqui e aqui ) e, como @Kevin Sylvestre sugeriu, você também pode usar os tipos aninhados como namespaces.
E para estender a resposta de Daniel A. White, na WWDC, eles estavam falando sobre os módulos rapidamente.
Também aqui é explicado:
fonte
Você não precisa prefixar e subclassar como este:
Faça isso deste modo:
Por quê? . Porque o que você declarou está declarado no módulo atual , que é seu destino atual . E
UICollectionViewController
deUIKit
é declarado noUIKit
módulo.Como usá-lo no módulo atual?
Como distingui-los de outro módulo?
fonte
Você pode usar
extension
astruct
abordagem mencionada para espaçamento de nomes sem precisar recuar todo o seu código para a direita. Venho brincando um pouco com isso e não tenho certeza se iria criar espaços para nomeControllers
eViews
nomes, como no exemplo abaixo, mas ilustra o quão longe ele pode ir:Profiles.swift :
Perfis / ViewControllers / Edit.swift
Perfis / Visualizações / Edit.swift
Não usei isso em um aplicativo, pois ainda não precisava desse nível de separação, mas acho que é uma ideia interessante. Isso elimina a necessidade de sufixos uniformes de classe, como o onipresente * ViewController, que é irritantemente longo.
No entanto, ele não reduz nada quando é referenciado, como em parâmetros de método como este:
fonte
Caso alguém tenha curiosidade, em 10 de junho de 2014, este é um bug conhecido no Swift:
From SevenTenEleven
"Erro conhecido, desculpe! Rdar: // problem / 17127940 A qualificação de tipos Swift pelo nome do módulo não funciona."
fonte