Skip to content

Instantly share code, notes, and snippets.

@MaisaMilena
Created March 15, 2022 02:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MaisaMilena/dc21f19ccde027494884f66c524acaa0 to your computer and use it in GitHub Desktop.
Save MaisaMilena/dc21f19ccde027494884f66c524acaa0 to your computer and use it in GitHub Desktop.

Se você é desenvolvedor Swift muito provavelmente já usou o tipo Result em algum código. Result é um um Generic Enumeration, e nos auxiliara lidar com requisições que podem dar certo - nos trazendo um valor de retorno, ou errado, resultando em um erro.

Ao realizar operações é bem comum que tenhamos no mínimo dois outputs; if-else, is nil or not e success-failure são bem familiares. Você já parou pra pensar no porquê essa estrutura funciona tão bem?

No caso success-failure, tem uma definição tal que:

enum Result<Success, Failure> where Failure : Error

Isto é, Result é um enum associado à dois tipos: Success e Failure, tal que Failure é do tipo Error.

Ao utiliza-lo, garantimos que apenas 1 dos casos/contrutores será satisfeito. Ele funciona assim:

enum Result<Success, Failure> where Failure : Error {
   case success(Success)
   case failure(Failure)
}

O construtor succcess está associado à um tipo Success (Tipo Genérico), que permite o reuso dessa estrutura pra diversos contextos. Já o construtor failure está associado à um tipo Error, que já é conhecido pelo Swift e também nos permite uma customização de erros.

load { [weak self] result in
    switch result {
    case .success(let data):
      self?.render(data)
    case .failure(let error):
      switch error {
      case .networkUnavailable:
          self?.showErrorView(withMessage: .offline)
      case .timedOut:
          self?.showErrorView(withMessage: .timedOut)
      }
    }
}

Algo parecido acontece com a estrutura do Optional, que na documentação do Swift diz que:

Optionals say either “there is a value, and it equals x” or “there isn’t a value at all”.

Onde:

enum Optional<Wrapped> {
  case none
  case some(value: Wrapped)
}

E o mesmo pode ser usado para representar se um ícone usará uma URL ou uma imagem default:

typealias IconResult<URL, UIImage> {
  case hasURL(URL)
  case defaultIcon(UIImage)
}

Essa estrutura comum à todos esses exemplos se chama Either e pode ser definida assim:

type Either<A: Type, B: Type> {
  left(value: A),
  right(value: B)
}

As utilidades são tantas que podemos até mesmo definir o que é um número e o que é uma lista!

type Nat {
  zero
  succ(pred: Nat)
}

type List<A: Type> {
  nil
  cons(head: A, tail: List<A>)
}

E aí, ficou curioso(a) em saber mais sobre Result e Either? Aqui vão algumas sugestões de leitura sobre o assunto:

Caso queira ir além e se aprofundar no uso de Enums, recomendo estudar sobre Algebraic Data Type (ADT).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment