Quando trabalhamos em projetos grandes e/ou em uma equipe de desenvolvimento é muito comum encontrarmos nomes iguais para tipos diferentes. Esse cenário também pode acontecer quando utilizamos framerworks de terceiros.
Vamos exemplificar o problema citado sobre nomenclaturas iguais e as três formas de resolvermos.
Exemplificando o problema
Digamos que a classe A possui uma classe B e C. A classe C possui uma estrutura com mesmo nome B e um método que recebe como parâmetro um tipo B. Quando olharmos para o código, sabemos que o parâmetro do método myMethod da classe C, refere-se a estrutura B.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
class A { | |
class B { | |
let number: Int | |
init(n: Int) { | |
self.number = n | |
} | |
} | |
class C { | |
struct B { | |
let str: String | |
} | |
static func myMethod(_ b: B) { | |
} | |
} | |
} |
Porém o que devemos fazer quando precisamos que o parâmetro do myMethod faça referência a classe B externa a C?
Opção 1
A primeira opção e acredito que a melhor é renomear o tipo duplicado e que faz menos sentido. Para isso o Xcode lançou desde a versão 9 uma ferramenta que particularmente eu gosto, mesmo com seus "pequenos" probleminhas - refatoração baseada no cursor.
![]() |
Fonte: https://swift.org/blog/swift-local-refactoring/ |
Com ela você pode alterar de uma vez todos que estão utilizando o tipo escolhido para refatorar.
Opção 2
Outra forma de resolvermos é inserindo o módulo em que faz parte. Por exemplo, sabemos que o framework UIKit da Apple possui um tipo chamado de UIColor, mas digamos que queremos criar o nosso próprio como value type e não reference type. Isso é permitido? Utilizando o mesmo nome? Sim, veja como ficaria:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
struct UIColor { | |
let value: UIKit.UIColor | |
init(_ color: UIKit.UIColor) { | |
self.value = color | |
} | |
} | |
let color = UIColor(UIKit.UIColor.black) | |
color.value.cgColor |
Observe que no código acima quando refere-se ao UIColor do framework UIKIt, inserimos com a indicação do módulo, no caso fica UIKit.UIColor. A mesma estratégia podemos utilizar no código apresentando no início do artigo:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
class A { | |
class B { | |
let number: Int | |
init(n: Int) { | |
self.number = n | |
} | |
} | |
class C { | |
struct B { | |
let str: String | |
} | |
static func myMethod(_ b: A.B) { | |
print("\(b.number)") | |
} | |
} | |
} | |
Essa opção só é válida se seu projeto possuir módulos separados, se os códigos não estiverem em um único target.
Opção 3
A terceira e última opção é declarar um type alias. Essa opção acho que só faz sentido se a renomeação for um problema ou não fizer sentido. Utilizando o código apresentado no início do artigo, podemos aplicar da seguinte maneira:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
typealias BClass = A.B | |
class A { | |
class B { | |
let number: Int | |
init(n: Int) { | |
self.number = n | |
} | |
} | |
class C { | |
struct B { | |
let str: String | |
} | |
static func myMethod(_ b: BClass) { | |
print("\(b.number)") | |
} | |
} | |
} |
A opção 2 já foi apresentada no Twitter pelo criador do Swift - Chris Lattner:
![]() |
Fonte: https://twitter.com/clattner_llvm/status/474772713739792384 |