Advertisement
  1. Code
  2. Swift

Dica Rápida: Enumerações em Swift

Scroll to top
Read Time: 7 min

() translation by (you can also view the original English article)

Enumerações é um padrão de projeto comum em muitas linguagens de programação.  Mesmo você tendo conhecimento de enumerações em C e Objective-C, a implementação de enumerações em Swift é significativamente mais poderosa e flexível. Nesta dica rápida, você vai aprender o que há de especial sobre enumerações em Swift, como usá-los em seus projetos e o que as torna tão poderosas.

1. O que é uma Enumeração?

Enumerações não são novas e certamente não são exclusivas para Swift. Porém, se você está familiarizado com enumerações em C, você irá adorar o quão poderosa são enumerações em Swift.

Se enums ou enumerações são novas para você, então você pode não estar familiarizado com o que elas tem a te oferecer. Em Swift, enumerações são tipos de primeira classe que define uma lista de possibilidades de valores este cada tipo.

Um exemplo pode ser os possíveis estados de uma conexão de rede. Os possíveis estados poderiam ser:

  • disconectado
  • conectando
  • conectado

Poderíamos adicionar um quarto estado para o caso de um estado desconhecido. Com este exemplo em mente, vamos ver como definir e implementar tal enumeração.

Básico

Como eu disse, enumerações são tipos de primeira classe no Swift. Uma definição de enumeração é muito similar a definição de uma classe ou estrutura. No exemplo a seguir, definimos a enumeração ConnectionState.

1
enum ConnectionState {
2
    
3
}

O nome da enumeração é precedido pela palavra-chave enum e seguido por um par de chaves. A enumeração ConectionState definirá os possíveis estados de uma conexão de rede. Para definir esses estados, adicionamos valores membro ou membros à definição da enumeração. A definição de um valor membro sempre começa com a palavra-chave case.

1
enum ConnectionState {
2
    case Unknown
3
    case Disconnected
4
    case Connecting
5
    case Connected
6
}

Em C ou Objective-C, a enumeração acima seria um pouco diferente, como ilustra o exemplo abaixo. Cada valor da enumeração corresponde a um inteiro, por exemplo, ConnectionStateUnknown é igual a 0, ConnectionStateDisconnected é igual a 1, etc.

1
typedef enum : NSUInteger {
2
    ConnectionStateUnknown,
3
    ConnectionStateDisconnected,
4
    ConnectionStateConnecting,
5
    ConnectionStateConnected
6
} ConnectionState;

Não é assim em Swift. Os membros de uma enumeração não correspondem automaticamente com um valor inteiro. Os membros da enumeração ConnectionState dão valores a si mesmos e são do tipo ConnectionState. Isto faz com que o trabalho com enumerações seja mais seguro e mais explícito.

Valores Bruto

É possível especificar explicitamente os valores dos membros de uma enumeração. No exemplo a seguir, os membros da enumeração ConnectionState tem um valor bruto do tipo Int. Cada membro é atribuído a um valor bruto, correspondente com um inteiro. 

1
enum ConnectionState: Int {
2
    case Unknown = -1
3
    case Disconnected = 0
4
    case Connecting = 1
5
    case Connected = 2
6
}

Note que especificamos o tipo do valor bruto na definição da enumeração e que dois valores membro não podem ter o mesmo valor bruto. Se especificarmos apenas um valor para o membro Unknown, então o Swift automaticamente incrementa o valor do membro Unknown e atribuir valores únicos para os outros membros da enumeração. Para melhor ilustrar isto, o exemplo abaixo é idêntico à definição anterior da enumeração ConnectionState.

1
enum ConnectionState: Int {
2
    case Unknown = -1
3
    case Disconnected
4
    case Connecting
5
    case Connected
6
}

2. Trabalhando com Enumerações

Inicialização

Usar a enumeração ConnectionState é semelhante ao uso de qualquer outro tipo em Swift. No próximo exemplo, declaramos uma variável, connectionState, e definimos seu valor com ConnectionState.Connectiong

1
var connectionState = ConnectionState.Connecting

O valor de connectionState é ConnectionState.Connecting e a variável é do tipo ConnectionState.

Inferência de tipo do Swift é muito conveniente quando se trabalha com enumerações. Como declaramos connectionState como sendo do tipo ConnectionState, agora podemos atribuir um novo valor usando a sintaxe de ponto para a enumeração.

1
connectionState = .Connected

Controle de Fluxo

Usar enumerações em uma instrução if ou switch é fácil. Lembre-se que instruções switch precisam ser exaustiva. Adicione um caso default se necessário.

1
enum ConnectionState {
2
    case Unknown
3
    case Disconnected
4
    case Connecting
5
    case Connected
6
}
7
8
var connectionState = ConnectionState.Connecting
9
10
connectionState = .Connected
11
12
switch connectionState {
13
    case .Disconnected:
14
        println("Disconnected")
15
    case .Connecting:
16
        println("Connecting")
17
    case .Connected:
18
        println("Connected")
19
    default:
20
        println("Unknown State")
21
}

O exemplo a seguir demonstra como a enumeração ConnectionState pode ser usada. Ele também mostra como acessar o valor associado de um membro de enum. A função canConnect recebe uma instância ConnectionState e retorna um Bool.

1
func canConnect(connectionState: ConnectionState) -> Bool {
2
    var result = false
3
    
4
    switch connectionState {
5
        case .Connected(let port):
6
            if port == 3000 {
7
                result = true
8
            }
9
        default:
10
            result = false
11
    }
12
    
13
    return result
14
}
15
16
let state = ConnectionState.Connected(3000)
17
18
if canConnect(state) {
19
    // ...

20
}

A função canConnect retorna true apenas se a instânciaConnectionState passada para a função for igual a .Connected e seu valor associado for um Int igual a 3000. Note que o valor associada do membro Connected é acessível na instrução switch como uma constante com o nome port, que podemos usar no case correspondente.

3. Valores Associados

Outro recurso atraente de enums em Swift são valores associados. Cada membro de um enum pode ter um valor associado. Valores associados são muito flexiveis. Por exemplo, valores associados de diferentes membros de um mesmo enum não precisam ser do mesmo tipo. Dê uma olhada no exemplo a seguir para entender melhor o conceito de valores associados.

1
enum ConnectionState {
2
    case Unknown
3
    case Disconnected
4
    case Connecting(Int, Double)
5
    case Connected(Int)
6
}

Os membros Unknown e Disconnected não tem um valor associado. O membro Connecting tem um valor associado do tipo (Int, Double), especificando o número da porta e o intervalo de tempo da conexão. O membro Connected tem um valor associado do tipo Int, especificando o número da porta.

É importante entender que um valor associado é ligado ou associado com um membro da enumeração. O valor do membro permanece inalterado. O próximo exemplo demonstra como criamos uma instância ConnectionState com um valor associado.  

1
var connectionState = ConnectionState.Connecting(3000, 30.0)

4. Métodos e Tipos de Valores

Métodos

Enumerações são muito poderosas em Swift. Enumerações podem até mesmo definir métodos, tais como um inicializador para selecionar um valor de membro padrão se nenhum foi especificado.

1
enum ConnectionState {
2
    case Unknown
3
    case Disconnected
4
    case Connecting(Int, Double)
5
    case Connected(Int)
6
    
7
    init () {
8
        self = .Unknown
9
    }
10
}
11
12
var connectionState = ConnectionState() // .Unknown

Neste exemplo, inicializamos uma instância da enumeração ConnectionState sem especificar explicitamente um valor para ele. No inicializador da enumeração, no entanto, definimos a instância para o Unknown. O resultado é que a variável connectionState é igual a ConnectionState.Unknown

Tipos de Valores

Como estruturas, enumerações são tipo de valor, o que significa que uma enumeração não é passada como referência, como a instância de uma classe, mas como valor. O exemplo a seguir demonstra isso.

1
var connectionState1 = ConnectionState()
2
var connectionState2 = connectionState1
3
4
connectionState1 = .Connected(1000)
5
6
println(connectionState1) // .Connected(1000)

7
println(connectionState2) // .Unknown

Mesmo que atribuímos connectionState1 para connectionState2, os valores de connectionState1 e connectionState2 são diferentes no final do exemplo.

Quando connectionState1 é atribuído a connectionState2, o Swift cria uma cópia do connectionState1 e atribui isso à connectionState2. Em outras palavras, connectionState1 e connectionState2 referem-se a duas instâncias diferentes de ConnectionState.

Conclusão

Enums em Swift é incrivelmente poderosas comparadas, por exemplo, a enums em C. Um dos aspectos mais poderoso da enumerações é que ela é de primeira classe em Swift. Type safety é um aspecto-chave da linguagem Swift e enumerações se encaixam perfeitamente nessa mentalidade.

Seja o primeiro a saber sobre novas traduções–siga @tutsplus_pt no Twitter!

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.