O Swift tem modificadores de acesso?


273

Em Objective-C, os dados da instância podem ser public, protectedou private. Por exemplo:

@interface Foo : NSObject
{
  @public
    int x;
  @protected:
    int y;
  @private:
    int z;
  }
-(int) apple;
-(int) pear;
-(int) banana;
@end

Não encontrei nenhuma menção de modificadores de acesso na referência Swift. É possível limitar a visibilidade dos dados no Swift?


Nem eu. A Apple deve pelo menos introduzir etiqueta para empresas privadas, como em python, elas são prefixadas com sublinhado.
Ciantic

Adicionada uma resposta atualizada para a versão final do Xcode 6.1.1
holroy 8/15

Respostas:


419

No Swift 3.0.1 , existem 4 níveis de acesso , descritos abaixo, do mais alto (menos restritivo) ao mais baixo (mais restritivo).


1. openepublic

Habilite uma entidade a ser usada fora do módulo de definição (destino). Você normalmente usa openou publicacessa ao especificar a interface pública para uma estrutura.

No entanto, o openacesso se aplica apenas a classes e membros da classe e difere do publicacesso da seguinte maneira:

  • public classes e membros da classe só podem ser subclassificados e substituídos no módulo de definição (destino).
  • open classes e membros da classe podem ser subclassificados e substituídos dentro e fora do módulo de definição (destino).

// First.framework – A.swift

open class A {}

// First.framework – B.swift

public class B: A {} // ok

// Second.framework – C.swift

import First

internal class C: A {} // ok

// Second.framework – D.swift

import First

internal class D: B {} // error: B cannot be subclassed

2) internal

Permite que uma entidade seja usada dentro do módulo de definição (destino). Você normalmente usa o internalacesso ao definir a estrutura interna de um aplicativo ou de uma estrutura.

// First.framework – A.swift

internal struct A {}

// First.framework – B.swift

A() // ok

// Second.framework – C.swift

import First

A() // error: A is unavailable

3) fileprivate

Restringe o uso de uma entidade ao seu arquivo de origem definidor. Você normalmente usa o fileprivateacesso para ocultar os detalhes de implementação de uma parte específica da funcionalidade quando esses detalhes são usados ​​em um arquivo inteiro.

// First.framework – A.swift

internal struct A {

    fileprivate static let x: Int

}

A.x // ok

// First.framework – B.swift

A.x // error: x is not available

4) private

Restringe o uso de uma entidade à sua declaração anexa. Você normalmente usa o privateacesso para ocultar os detalhes de implementação de uma parte específica da funcionalidade quando esses detalhes são usados ​​apenas em uma única declaração.

// First.framework – A.swift

internal struct A {

    private static let x: Int

    internal static func doSomethingWithX() {
        x // ok
    }

}

A.x // error: x is unavailable

37
Alguém poderia me explicar por que isso não é grande coisa?
Zaky German

15
sempre alguns métodos ou variáveis em OOP que devem ser privada ou protegida. Isso permite a implementação do design do SOLID , pois os métodos grandes são divididos em vários métodos menores, cada um com sua própria responsabilidade, que pode ser substituído, mas apenas o método "principal" deve estar disponível para uso público.
akashivskyy

19
Eu, pessoalmente, não gosto de soluções como aquela com os métodos "particulares" principais de sublinhado / caractere especial. Mesmo que seja garantido que eu, por mim mesmo, seja a única pessoa a dar uma olhada nesse código, ele o tornará mais salvo / menos propenso a erros, pois o compilador simplesmente impedirá que você faça coisas que não deve fazer. Então, acho que eles devem divulgar os "mecanismos de controle de acesso" o mais rápido possível, para que as pessoas não se acostumem a maus hábitos.
Jonas Eschmann

10
As notas de versão beta do Xcode 6 dizem: "O controle de acesso (membros públicos / privados) não está ativado nesta semente. (15747445)"
Martin Ullrich

9
@alcalde A idéia de uma interface pública é altamente valiosa. Se você pretende que todo o código de uma classe deva residir em funções que fazem parte da API pública, acho que isso é bastante limitante. Por outro lado, ter uma API pública especificada permite que a implementação mude (incluindo o uso de métodos privados) sem atrapalhar os consumidores. Se alguém "precisa" usar um método de classe interno, sinto que eles não entendem os limites da funcionalidade da classe (ou estão tentando usar uma classe de buggy).
Jinglesthula

26

Swift 4 / Swift 5

Conforme mencionado na documentação do Swift - Controle de acesso , o Swift possui 5 controles de acesso :

  • aberto e público : pode ser acessado a partir das entidades de seu módulo e de qualquer entidade do módulo que importe o módulo de definição.

  • internal : só pode ser acessado a partir das entidades de seus módulos. É o nível de acesso padrão.

  • fileprivate e private : só pode ser acessado de forma limitada dentro de um escopo limitado onde você os define.



Qual é a diferença entre open e public ?

open é o mesmo que public nas versões anteriores do Swift, elas permitem que classes de outros módulos as usem e as herdem, ou seja: elas podem ser subclassificadas de outros módulos. Além disso, eles permitem que membros de outros módulos os usem e os substituam. A mesma lógica vale para seus módulos.

O público permite que classes de outro módulo as usem, mas não as herdem, ou seja: elas não podem ser subclassificadas de outros módulos. Além disso, eles permitem que membros de outros módulos os usem, mas NÃO os substituam. Para seus módulos, eles têm a mesma lógica de abertura (eles permitem que as classes os usem e herdam; eles permitem que os membros os usem e os substituam).


Qual é a diferença entre fileprivate e private ?

fileprivate pode ser acessado a partir de seus arquivos inteiros.

private só pode ser acessado a partir de sua única declaração e a extensões dessa declaração que estão no mesmo arquivo; Por exemplo:

// Declaring "A" class that has the two types of "private" and "fileprivate":
class A {
    private var aPrivate: String?
    fileprivate var aFileprivate: String?

    func accessMySelf() {
        // this works fine
        self.aPrivate = ""
        self.aFileprivate = ""
    }
}

// Declaring "B" for checking the abiltiy of accessing "A" class:
class B {
    func accessA() {
        // create an instance of "A" class
        let aObject = A()

        // Error! this is NOT accessable...
        aObject.aPrivate = "I CANNOT set a value for it!"

        // this works fine
        aObject.aFileprivate = "I CAN set a value for it!"
    }
}



Quais são as diferenças entre o Swift 3 e o Swift 4 Access Control?

Conforme mencionado na proposta SE-0169 , o único refinamento foi adicionado ao Swift 4 é que o escopo de controle de acesso privado foi expandido para ser acessível a partir de extensões dessa declaração no mesmo arquivo; Por exemplo:

struct MyStruct {
    private let myMessage = "Hello World"
}

extension MyStruct {
    func printMyMessage() {
        print(myMessage)
        // In Swift 3, you will get a compile time error:
        // error: 'myMessage' is inaccessible due to 'private' protection level

        // In Swift 4 it should works fine!
    }
}

Portanto, não há necessidade de declarar myMessagecomo arquivo privado acessível em todo o arquivo.


17

Quando se fala em criar um "método privado" no Swift ou ObjC (ou ruby, java ou ...), esses métodos não são realmente privados. Não há controle de acesso real em torno deles. Qualquer linguagem que ofereça um pouco de introspecção permite que os desenvolvedores cheguem a esses valores de fora da classe, se realmente quiserem.

Então, o que realmente estamos falando aqui é uma maneira de definir uma interface voltada para o público que apenas apresenta a funcionalidade que queremos e "oculta" o resto que consideramos "privado".

O mecanismo Swift para declarar interfaces é o protocol, e pode ser usado para essa finalidade.

protocol MyClass {
  var publicProperty:Int {get set}
  func publicMethod(foo:String)->String
}

class MyClassImplementation : MyClass {
  var publicProperty:Int = 5
  var privateProperty:Int = 8

  func publicMethod(foo:String)->String{
    return privateMethod(foo)
  }

  func privateMethod(foo:String)->String{
    return "Hello \(foo)"
  }
}

Lembre-se de que os protocolos são tipos de primeira classe e podem ser usados ​​em qualquer lugar que um tipo puder. E , quando usados ​​dessa maneira, eles apenas expõem suas próprias interfaces, não aquelas do tipo de implementação.

Assim, contanto que você use em MyClassvez de MyClassImplementationnos tipos de parâmetro, etc. tudo funcionará:

func breakingAndEntering(foo:MyClass)->String{
  return foo.privateMethod()
  //ERROR: 'MyClass' does not have a member named 'privateMethod'
}

Existem alguns casos de atribuição direta em que você precisa ser explícito com o tipo, em vez de confiar no Swift para deduzi-lo, mas isso dificilmente parece um rompimento de negócio:

var myClass:MyClass = MyClassImplementation()

O uso de protocolos dessa maneira é semântico, razoavelmente conciso e, aos meus olhos, se parece muito com as Extensões de Classe que estamos usando para esse objetivo no ObjC.


1
Se os protocolos não nos permitem ter um argumento padrão, como posso criar um método público com parâmetros opcionais que ainda estejam em conformidade com o protocolo?
bdurao

Eu não entendo o que você quer dizer. A seguir, cria um método público com um parâmetro opcional. Não parece haver um problema: gist.github.com/anonymous/17d8d2d25a78644046b6
jemmons

Por alguma razão, o parâmetro opcional não está funcionando como deveria no meu projeto, já havia tentado algo semelhante ao seu exemplo do GitHub. Como não podemos definir um parâmetro padrão em um protocolo, fiquei preso e acabei fazendo uma pergunta. Obrigado por tentar ajudar.
bdurao 31/07

Todos sabemos que qualquer coisa pode ser hackeada. Nós só precisamos de alguns que é de ordem porque nós necessitamos modificadores de acesso
canbax

14

Até onde eu sei, não há palavras-chave 'público', 'privado' ou 'protegido'. Isso sugere que tudo é público.

No entanto, a Apple pode esperar que as pessoas usem " protocolos " (chamados de interfaces pelo resto do mundo) e o padrão de design de fábrica para ocultar detalhes do tipo de implementação.

Geralmente, esse é um bom padrão de design a ser usado; pois permite alterar sua hierarquia de classes de implementação , mantendo o mesmo sistema de tipo lógico .


Isso é bom, pois também reduz o acoplamento e pode facilitar o teste.
precisa saber é o seguinte

4
Isso funcionaria melhor se houvesse uma maneira de ocultar a classe de implementação do protocolo, mas não parece existir.
David Moles

Alguém pode fornecer um exemplo ilustrativo desse padrão?
bloudermilk

Bem, esta resposta foi válida nas versões Swift anteriores, parece que não é mais válida :) verifique minha resposta .
Ahmad F

12

Usando uma combinação de protocolos, fechamentos e classes aninhadas / internas, é possível usar algo ao longo das linhas do padrão do módulo para ocultar as informações no Swift agora. Não é super limpo ou agradável de ler, mas funciona.

Exemplo:

protocol HuhThing {
  var huh: Int { get set }
}

func HuhMaker() -> HuhThing {
   class InnerHuh: HuhThing {
    var innerVal: Int = 0
    var huh: Int {
      get {
        return mysteriousMath(innerVal)
      }

      set {
       innerVal = newValue / 2
      }
    }

    func mysteriousMath(number: Int) -> Int {
      return number * 3 + 2
    }
  }

  return InnerHuh()
}

HuhMaker()
var h = HuhMaker()

h.huh      // 2
h.huh = 32 
h.huh      // 50
h.huh = 39
h.huh      // 59

innerVal e mysteriousMath estão ocultos aqui do uso externo e a tentativa de cavar seu caminho no objeto deve resultar em um erro.

Eu sou apenas parte do caminho através da minha leitura dos documentos do Swift, por isso, se houver uma falha aqui, indique-a, gostaria de saber.


ok, pensei sobre essa solução também, mas explique-me, por que não consigo acessar h.huh.innerVal?
Sam

Swift é seguro para o tipo e a única coisa que o mundo externo sabe sobre h é que ele está em conformidade com o HuhThing. O HuhThing não inclui nenhuma informação sobre uma propriedade chamada innerVal e, portanto, tentar acessá-la é um erro.
precisa

8
Ainda acessível: Preflect(h)[0].1.value // 19
John Estropia

2
Bom encontrar lá John - eu não estava ciente de refletir. Parece transformar objetos em Tuplas - existe alguma documentação oficial sobre essa função ou outras coisas de metaprogramação no Swift? Dei uma olhada no guia de idiomas do iBooks, mas não o vejo.
Dave Kapp

1
@ JohnEstropia Eu não acho que a reflexão conta. Em Java (a mais maduro linguagem), não são modificadores de acesso, mas eles não impedem reflexão truques também.
11684

10

A partir do Xcode 6 beta 4, o Swift possui modificadores de acesso. Nas notas de versão:

O controle de acesso rápido tem três níveis de acesso:

  • entidades privadas podem ser acessadas apenas de dentro do arquivo de origem onde estão definidas.
  • entidades internas podem ser acessadas em qualquer lugar do destino em que estão definidas.
  • entidades públicas podem ser acessadas de qualquer lugar dentro do destino e de qualquer outro contexto que importe o módulo do destino atual.

O padrão implícito é que internal, dentro de um destino de aplicativo, você pode deixar os modificadores de acesso desativados, exceto onde deseja ser mais restritivo. Em um destino da estrutura (por exemplo, se você estiver incorporando uma estrutura para compartilhar código entre um aplicativo e um compartilhamento ou a extensão de exibição Hoje), use publicpara designar a API que você deseja expor aos clientes da sua estrutura.


Bem, esta resposta foi válida nas versões Swift anteriores, parece que não é mais válida :) verifique minha resposta .
Ahmad F

6

O Swift 3.0 fornece cinco controles de acesso diferentes:

  1. abrir
  2. público
  3. interno
  4. fileprivate
  5. privado

O acesso aberto e o acesso público permitem que as entidades sejam usadas em qualquer arquivo de origem de seu módulo de definição e também em um arquivo de origem de outro módulo que importe o módulo de definição. Você normalmente usa acesso aberto ou público ao especificar a interface pública para uma estrutura.

O acesso interno permite que as entidades sejam usadas em qualquer arquivo de origem de seu módulo de definição, mas não em nenhum arquivo de origem fora desse módulo. Você normalmente usa acesso interno ao definir a estrutura interna de um aplicativo ou de uma estrutura.

O acesso privado a arquivos restringe o uso de uma entidade ao seu próprio arquivo de origem definidor. Use o acesso privado a arquivos para ocultar os detalhes de implementação de uma parte específica da funcionalidade quando esses detalhes forem usados ​​em um arquivo inteiro.

O acesso privado restringe o uso de uma entidade à declaração anexa. Use o acesso privado para ocultar os detalhes de implementação de uma parte específica da funcionalidade quando esses detalhes forem usados ​​apenas em uma única declaração.

O acesso aberto é o nível de acesso mais alto (menos restritivo) e o acesso privado é o nível de acesso mais baixo (mais restritivo).

Níveis de acesso padrão

Todas as entidades em seu código (com algumas exceções específicas) têm um nível de acesso interno padrão, se você não especificar um nível de acesso explícito. Como resultado, em muitos casos, você não precisa especificar um nível de acesso explícito no seu código.

A nota de versão sobre o tópico:

Classes declaradas como públicas não podem mais ser subclassificadas fora de seu módulo de definição e métodos declarados como públicos não podem mais ser substituídos fora de seu módulo de definição. Para permitir que uma classe seja subclassificada externamente ou que um método seja substituído externamente, declare-as como abertas, que é um novo nível de acesso além do público. As classes e os métodos Objective-C importados agora são todos importados como abertos, em vez de públicos. Os testes de unidade que importam um módulo usando uma importação @testable ainda poderão subclassificar classes públicas ou internas, bem como substituir métodos públicos ou internos. (SE-0117)

Mais informações e detalhes: A linguagem de programação Swift (controle de acesso)


Bem, esta resposta foi válida nas versões Swift anteriores, parece que não é mais válida :) verifique minha resposta .
Ahmad F

4

Na versão Beta 6, a documentação afirma que existem três modificadores de acesso diferentes:

  • Público
  • interno
  • Privado

E esses três se aplicam a classes, protocolos, funções e propriedades.

public var somePublicVariable = 0
internal let someInternalConstant = 0
private func somePrivateFunction() {}

Para mais, consulte Controle de acesso .


Deveria haver um modificador protegido que facilita a criação de classes com maior segurança.
Kumar C

Bem, esta resposta foi válida nas versões Swift anteriores, parece que não é mais válida :) verifique minha resposta .
Ahmad F

2

Agora na versão beta 4, eles adicionaram modificadores de acesso ao Swift.

do Xcode 6 beta 4 notas em realese :

O controle de acesso rápido tem três níveis de acesso:

  • private as entidades podem ser acessadas somente a partir do arquivo de origem onde são definidas.
  • internal as entidades podem ser acessadas em qualquer lugar dentro do destino em que são definidas.
  • public entidades podem ser acessadas de qualquer lugar dentro do destino e de qualquer outro contexto que importe o módulo do destino atual.

Por padrão, a maioria das entidades em um arquivo de origem tem acesso interno. Isso permite que os desenvolvedores de aplicativos ignorem amplamente o controle de acesso, enquanto permitem que os desenvolvedores da estrutura tenham controle total sobre a API da estrutura.


Você pode postar um link para isso?
21414 Boneco de neve

Bem, esta resposta foi válida nas versões Swift anteriores, parece que não é mais válida :) verifique minha resposta .
Ahmad F

2

Mecanismos de controle de acesso, conforme introduzidos no Xcode 6 :

O Swift fornece três níveis de acesso diferentes para entidades dentro do seu código. Esses níveis de acesso são relativos ao arquivo de origem no qual uma entidade está definida e também ao módulo ao qual o arquivo de origem pertence.

  • O acesso público permite que as entidades sejam usadas em qualquer arquivo de origem de seu módulo de definição e também em um arquivo de origem de outro módulo que importe o módulo de definição. Você geralmente usa acesso público ao especificar a interface pública para uma estrutura.
  • O acesso interno permite que as entidades sejam usadas em qualquer arquivo de origem de seu módulo de definição, mas não em nenhum arquivo de origem fora desse módulo. Você normalmente usa acesso interno ao definir a estrutura interna de um aplicativo ou de uma estrutura.
  • O acesso privado restringe o uso de uma entidade ao seu próprio arquivo de origem definidor. Use o acesso privado para ocultar os detalhes de implementação de uma parte específica da funcionalidade.

O acesso público é o nível de acesso mais alto (menos restritivo) e o acesso privado é o nível de acesso mais baixo (ou mais restritivo).

O padrão é interno e, como tal, não precisa ser especificado. Observe também que o especificador privado não funciona no nível da classe, mas no nível do arquivo de origem. Isso significa que, para tornar partes de uma classe realmente privadas, é necessário separar em um arquivo próprio. Isso também apresenta alguns casos interessantes com relação ao teste de unidade ...

Outro ponto para mim, que é comentado no link acima, é que você não pode 'atualizar' o nível de acesso. Se você subclassificar algo, poderá restringi-lo mais, mas não o contrário.

Esse último bit também afeta funções, tuplas e, certamente, outras coisas da mesma maneira que, se uma função usa uma classe privada , não é válido ter a função interna ou pública , pois elas podem não ter acesso à classe privada . Isso resulta em um aviso do compilador e você precisa redeclarar a função como uma função privada .


Bem, esta resposta foi válida nas versões Swift anteriores, parece que não é mais válida :) verifique minha resposta .
Ahmad F

2

Swift 3 e 4 trouxeram muitas mudanças também para os níveis de acesso de variáveis ​​e métodos. O Swift 3 e 4 agora tem 4 níveis de acesso diferentes, em que o acesso público / aberto é o nível de acesso mais alto (menos restritivo) e o acesso privado é o nível de acesso mais baixo (mais restritivo):

  • funções privadas e membros só podem ser acessados ​​a partir do escopo da própria entidade (struct, classe,…) e suas extensões (no Swift 3 também as extensões eram restritas)
  • funções e membros fileprivate só podem ser acessados ​​a partir do arquivo de origem onde são declarados.
  • funções e membros internos (que é o padrão, se você não adicionar explicitamente uma palavra-chave no nível de acesso) podem ser acessados ​​em qualquer lugar do destino em que estão definidos. É por isso que o TestTarget não tem acesso automático a todas as fontes; elas devem ser marcadas como acessíveis no inspetor de arquivos do xCode.
  • funções e membros abertos ou públicos podem ser acessados ​​de qualquer lugar dentro do destino e de qualquer outro contexto que importe o módulo do destino atual.

Interessante:

Em vez de marcar cada método ou membro como "privado", você pode cobrir alguns métodos (por exemplo, funções auxiliares) em uma extensão de uma classe / estrutura e marcar toda a extensão como "Privada".

class foo { }

private extension foo {
    func somePrivateHelperFunction01() { }
    func somePrivateHelperFunction02() { }
    func somePrivateHelperFunction03() { }
}

Essa pode ser uma boa ideia, a fim de obter um melhor código de manutenção. E você pode facilmente mudar (por exemplo, para teste de unidade) para não-privado, alterando apenas uma palavra.

Documentação da Apple


Bem, esta resposta foi válida nas versões Swift anteriores, parece que não é mais válida :) verifique minha resposta .
Ahmad F

2

Para Swift 1-3:

Não, não é possível. Não existem métodos e variáveis ​​privados / protegidos.

Tudo é público.

Atualização Desde o Swift 4, é possível ver outras respostas neste tópico


1
Este comentário é preciso para a semente atual.
Jesper

2
Para a semente atual. Aparecerá no futuro .
Jesper

1
"public" / "protected" / "private" não existem atualmente, mas você pode ocultar itens usando fechamentos, protocolos e classes internas - isso é semelhante ao padrão de módulo usado no JavaScript normalmente. Por favor, veja meu código de amostra na minha resposta aqui para um exemplo de como fazer isso. Se eu estiver enganado sobre como isso funciona e meu exemplo estiver incorreto, indique isso, pois ainda estou aprendendo também. :)
Dave Kapp

Parece que não é mais válido :) por favor, verifique minha resposta .
Ahmad F

1

Uma das opções que você pode usar é agrupar a criação da instância em uma função e fornecer os getters e setters apropriados em um construtor:

class Counter {
    let inc: () -> Int
    let dec: () -> Int

    init(start: Int) {
        var n = start

        inc = { ++n }
        dec = { --n }
    }
}


let c = Counter(start: 10)

c.inc()  // 11
c.inc()  // 12
c.dec()  // 11

0

A gramática do idioma não possui as palavras-chave "público", "privado" ou "protegido". Isso sugere que tudo é público. Obviamente, poderia haver algum método alternativo de especificar modificadores de acesso sem essas palavras-chave, mas não consegui encontrá-lo na referência de idioma.


0

Esperamos poupar algum tempo para aqueles que desejam algo semelhante aos métodos protegidos:

Conforme outras respostas, o swift agora fornece o modificador 'private' - que é definido em termos de arquivo, e não em classe, como em Java ou C #, por exemplo. Isso significa que, se você quiser métodos protegidos, poderá fazê-lo com métodos privados rápidos, se estiverem no mesmo arquivo

  1. Crie uma classe base para manter os métodos 'protegidos' (na verdade privados)
  2. Subclasse essa classe para usar os mesmos métodos
  3. Em outros arquivos, você não pode acessar os métodos da classe base, mesmo quando você subclassifica

por exemplo, arquivo 1:

class BaseClass {
    private func protectedMethod() {

    }
}

class SubClass : BaseClass {
    func publicMethod() {
        self.protectedMethod()  //this is ok as they are in same file
    }
}

Arquivo 2:

func test() {
    var a = BaseClass()
    a.protectedMethod() //ERROR


    var b = SubClass()
    b.protectedMethod() //ERROR
}

class SubClass2 : BaseClass {
    func publicMethod() {
        self.protectedMethod() //ERROR
    }

}



-2

Até o Swift 2.0, havia apenas três níveis de acesso [Público, Interno, Privado], mas no Swift 3.0, a Apple adicionou dois novos níveis de acesso, que são [Open, fileType]. Agora, no Swift 3.0, existem 5 níveis de acesso. Aqui eu quero limpar o papel destes dois níveis de acesso 1. Aberto: é muito semelhante ao Público, mas a única diferença é que o Público pode acessar a subclasse e substituir, e o Nível de acesso aberto não pode acessar que esta imagem foi retirada do site Medium e descreve a diferença entre acesso aberto e público

Agora, para o segundo novo nível de acesso 2. o tipo de arquivo é uma versão maior do nível de acesso privado ou menos do que o interno O fileType pode acessar a parte estendida da [classe, estrutura, enum] e o privado não pode acessar a parte estendida do código que só pode acessar o escopo lexical em que esta imagem é obtida no site Medium e descreve a diferença entre fileType e nível de acesso privado

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.