swift generic Constantes rápidas: Struct ou Enum




opaque types swift (3)

Não sei ao certo qual dos dois é melhor para definir constantes. Uma estrutura ou uma enumeração. Uma estrutura será copiada toda vez que eu usá-lo ou não? Quando penso em uma estrutura com constantes static let não faz sentido que ele seja copiado o tempo todo, na minha opinião. Mas se não for copiado, não importa o que eu leve?

Quais vantagens a escolha de uma estrutura ou enum?

Francisco diz que use Struct.

Ray Wunderlich diz que usa o Enum. Mas eu não tenho a justificativa.


Answer #1

Aqui está uma resposta curta: Suas constantes precisam ser únicas? Em seguida, use uma enumeração que imponha isso.

Deseja usar várias constantes diferentes para conter o mesmo valor (geralmente útil para maior clareza)? Em seguida, use uma estrutura que permita isso.


Answer #2

Estruturas e enumerações funcionam. Como exemplo, ambos

struct PhysicalConstants {
    static let speedOfLight = 299_792_458
    // ...
}

e

enum PhysicalConstants {
    static let speedOfLight = 299_792_458
    // ...
}

trabalhe e defina uma propriedade estática PhysicalConstants.speedOfLight .

Re: Uma estrutura será copiada toda vez que eu usá-lo ou não?

struct e enum são tipos de valor, de modo que também se aplicariam às enumerações. Mas isso é irrelevante aqui porque você não precisa criar um valor: Propriedades estáticas (também chamadas de propriedades de tipo ) são propriedades do próprio tipo, não de uma instância desse tipo.

Re: Quais vantagens tem a escolha de uma estrutura ou enum?

Conforme mencionado no artigo vinculado :

A vantagem de usar uma enumeração sem maiúsculas e minúsculas é que ela não pode ser instanciada acidentalmente e funciona como um namespace puro.

Então, para uma estrutura,

let foo = PhysicalConstants()

cria um valor (inútil) do tipo PhysicalConstants , mas para uma enumeração sem caixa, ele falha ao compilar:

let foo = PhysicalConstants()
// error: 'PhysicalConstants' cannot be constructed because it has no accessible initializers

Answer #3

Usando o Xcode 7.3.1 e o Swift 2.2

Embora eu concorde com Martin R, e o guia de estilo Ray Wenderlich enfatize que as enumerações são melhores em quase todos os casos de uso, por ser um espaço de nome puro, há um local em que o uso de uma struct supera enums .

Instruções de troca

Vamos começar com a versão struct:

struct StaticVars {
    static let someString = "someString"
}

switch "someString" {
case StaticVars.someString: print("Matched StaticVars.someString")
default: print("Didn't match StaticVars.someString")
}

Usando uma estrutura, isso corresponderá e imprimirá o Matched StaticVars.someString .

Agora vamos considerar a versão sem enum (sem alterar a palavra-chave struct para enum ):

enum StaticVars {
    static let someString = "someString"
}

switch "someString" {
case StaticVars.someString: print("Matched StaticVars.someString")
default: print("Didn't match StaticVars.someString")
}

Você notará que obtém um erro de tempo de compilação na instrução switch no case StaticVars.someString: line. O erro é o Enum case 'someString' not found in type 'String' .

Há uma pseudo-solução alternativa, convertendo a propriedade estática em um fechamento que retorna o tipo.

Então você mudaria assim:

enum StaticVars {
    static let someString = { return "someString" }
}

switch "someString" {
case StaticVars.someString(): print("Matched StaticVars.someString")
default: print("Didn't match StaticVars.someString")
}

Observe a necessidade de parênteses na instrução case, porque agora é uma função.

A desvantagem é que agora que fizemos uma função, ela é executada toda vez que é invocada. Portanto, se é apenas um tipo primitivo simples como String ou Int , isso não é tão ruim. É essencialmente uma propriedade computada. Se é uma constante que precisa ser calculada e você deseja calculá-la apenas uma vez, considere calculá-la em uma propriedade diferente e retornar esse valor já calculado no fechamento.

Você também pode substituir o inicializador padrão por um particular e, em seguida, obterá o mesmo tipo de benefício de erro de tempo de compilação que o enum sem caixa.

struct StaticVars {
    static let someString = "someString"
    private init() {}
}

Mas com isso, você desejaria colocar a declaração da estrutura em seu próprio arquivo, porque se a declarasse no mesmo arquivo que, digamos, uma classe View Controller, o arquivo dessa classe ainda seria capaz de instanciar acidentalmente um objeto inútil. instância de StaticVars , mas fora do arquivo da classe funcionaria como pretendido. Mas a decisão é sua.





constants