├── CONTRIBUTING.md ├── LICENSE ├── README-PTBR.md └── README.md /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | This guide is primarily intended to be _descriptive_, detailing the usage 2 | that Swift developers at GitHub have arrived at in cases of disagreement. 3 | Consider whether a proposed addition would make more sense in a fork used 4 | by your projects/organization instead. 5 | 6 | If you want to suggest a change or addition that will help accomplish 7 | [the goals](README.md) of this style guide, please open a pull request that: 8 | 9 | 1. Explains the guideline 10 | 1. Demonstrates the guideline with more-or-less valid example code 11 | 1. Justifies the guideline by explaining the rationale behind it 12 | 13 | Just note that all suggestions are open to discussion and debate! :smile: 14 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | CC0 1.0 Universal 2 | 3 | Statement of Purpose 4 | 5 | The laws of most jurisdictions throughout the world automatically confer 6 | exclusive Copyright and Related Rights (defined below) upon the creator and 7 | subsequent owner(s) (each and all, an "owner") of an original work of 8 | authorship and/or a database (each, a "Work"). 9 | 10 | Certain owners wish to permanently relinquish those rights to a Work for the 11 | purpose of contributing to a commons of creative, cultural and scientific 12 | works ("Commons") that the public can reliably and without fear of later 13 | claims of infringement build upon, modify, incorporate in other works, reuse 14 | and redistribute as freely as possible in any form whatsoever and for any 15 | purposes, including without limitation commercial purposes. These owners may 16 | contribute to the Commons to promote the ideal of a free culture and the 17 | further production of creative, cultural and scientific works, or to gain 18 | reputation or greater distribution for their Work in part through the use and 19 | efforts of others. 20 | 21 | For these and/or other purposes and motivations, and without any expectation 22 | of additional consideration or compensation, the person associating CC0 with a 23 | Work (the "Affirmer"), to the extent that he or she is an owner of Copyright 24 | and Related Rights in the Work, voluntarily elects to apply CC0 to the Work 25 | and publicly distribute the Work under its terms, with knowledge of his or her 26 | Copyright and Related Rights in the Work and the meaning and intended legal 27 | effect of CC0 on those rights. 28 | 29 | 1. Copyright and Related Rights. A Work made available under CC0 may be 30 | protected by copyright and related or neighboring rights ("Copyright and 31 | Related Rights"). Copyright and Related Rights include, but are not limited 32 | to, the following: 33 | 34 | i. the right to reproduce, adapt, distribute, perform, display, communicate, 35 | and translate a Work; 36 | 37 | ii. moral rights retained by the original author(s) and/or performer(s); 38 | 39 | iii. publicity and privacy rights pertaining to a person's image or likeness 40 | depicted in a Work; 41 | 42 | iv. rights protecting against unfair competition in regards to a Work, 43 | subject to the limitations in paragraph 4(a), below; 44 | 45 | v. rights protecting the extraction, dissemination, use and reuse of data in 46 | a Work; 47 | 48 | vi. database rights (such as those arising under Directive 96/9/EC of the 49 | European Parliament and of the Council of 11 March 1996 on the legal 50 | protection of databases, and under any national implementation thereof, 51 | including any amended or successor version of such directive); and 52 | 53 | vii. other similar, equivalent or corresponding rights throughout the world 54 | based on applicable law or treaty, and any national implementations thereof. 55 | 56 | 2. Waiver. To the greatest extent permitted by, but not in contravention of, 57 | applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and 58 | unconditionally waives, abandons, and surrenders all of Affirmer's Copyright 59 | and Related Rights and associated claims and causes of action, whether now 60 | known or unknown (including existing as well as future claims and causes of 61 | action), in the Work (i) in all territories worldwide, (ii) for the maximum 62 | duration provided by applicable law or treaty (including future time 63 | extensions), (iii) in any current or future medium and for any number of 64 | copies, and (iv) for any purpose whatsoever, including without limitation 65 | commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes 66 | the Waiver for the benefit of each member of the public at large and to the 67 | detriment of Affirmer's heirs and successors, fully intending that such Waiver 68 | shall not be subject to revocation, rescission, cancellation, termination, or 69 | any other legal or equitable action to disrupt the quiet enjoyment of the Work 70 | by the public as contemplated by Affirmer's express Statement of Purpose. 71 | 72 | 3. Public License Fallback. Should any part of the Waiver for any reason be 73 | judged legally invalid or ineffective under applicable law, then the Waiver 74 | shall be preserved to the maximum extent permitted taking into account 75 | Affirmer's express Statement of Purpose. In addition, to the extent the Waiver 76 | is so judged Affirmer hereby grants to each affected person a royalty-free, 77 | non transferable, non sublicensable, non exclusive, irrevocable and 78 | unconditional license to exercise Affirmer's Copyright and Related Rights in 79 | the Work (i) in all territories worldwide, (ii) for the maximum duration 80 | provided by applicable law or treaty (including future time extensions), (iii) 81 | in any current or future medium and for any number of copies, and (iv) for any 82 | purpose whatsoever, including without limitation commercial, advertising or 83 | promotional purposes (the "License"). The License shall be deemed effective as 84 | of the date CC0 was applied by Affirmer to the Work. Should any part of the 85 | License for any reason be judged legally invalid or ineffective under 86 | applicable law, such partial invalidity or ineffectiveness shall not 87 | invalidate the remainder of the License, and in such case Affirmer hereby 88 | affirms that he or she will not (i) exercise any of his or her remaining 89 | Copyright and Related Rights in the Work or (ii) assert any associated claims 90 | and causes of action with respect to the Work, in either case contrary to 91 | Affirmer's express Statement of Purpose. 92 | 93 | 4. Limitations and Disclaimers. 94 | 95 | a. No trademark or patent rights held by Affirmer are waived, abandoned, 96 | surrendered, licensed or otherwise affected by this document. 97 | 98 | b. Affirmer offers the Work as-is and makes no representations or warranties 99 | of any kind concerning the Work, express, implied, statutory or otherwise, 100 | including without limitation warranties of title, merchantability, fitness 101 | for a particular purpose, non infringement, or the absence of latent or 102 | other defects, accuracy, or the present or absence of errors, whether or not 103 | discoverable, all to the greatest extent permissible under applicable law. 104 | 105 | c. Affirmer disclaims responsibility for clearing rights of other persons 106 | that may apply to the Work or any use thereof, including without limitation 107 | any person's Copyright and Related Rights in the Work. Further, Affirmer 108 | disclaims responsibility for obtaining any necessary consents, permissions 109 | or other rights required for any use of the Work. 110 | 111 | d. Affirmer understands and acknowledges that Creative Commons is not a 112 | party to this document and has no duty or obligation with respect to this 113 | CC0 or use of the Work. 114 | 115 | For more information, please see 116 | -------------------------------------------------------------------------------- /README-PTBR.md: -------------------------------------------------------------------------------- 1 | Um guia de estilo e convenções de programação para projetos em Swift 2 | 3 | Esta é uma tentativa de incentivar padrões para alcançar os seguintes objetivos (mais ou menos em ordem de prioridade): 4 | 5 | 1. Maior rigor e diminuição da probabilidade de erro do programador 6 | 1. Aumento da clareza de intenção 7 | 1. Verbosidade reduzida 8 | 1. Menos debates sobre estética 9 | 10 | Se você tiver sugestões, por favor, consulte as nossas [orientações de contribuição] (CONTRIBUTING.md), em seguida, abra uma pull request. :zap: 11 | 12 | ---- 13 | 14 | #### Espaços em branco 15 | 16 | * Tabs, não espaços. 17 | * Termine arquivos com novas linhas. 18 | * Use espaços em branco verticais à vontade para dividir o código em blocos lógicos. 19 | * Não deixe espaços em branco no final das linhas 20 | * Nem mesmo indentação em linhas em branco. 21 | 22 | #### Prefira `let`-bindings a ` var`-bindings sempre que possível 23 | 24 | Use `let foo = ...` ao invés de `var foo = ...` sempre que possível (e em caso de dúvida). Só use `var` se for absolutamente necessário (isto é, você *sabe* que o valor pode mudar, por exemplo, quando se utiliza o modificador de armazenamento `weak`). 25 | 26 | _Justificativa:_ A intenção e o significado de ambas palavras-chave são claros, mas *let-como-padrão* resulta em código mais seguro e mais claro. 27 | 28 | Um `let`-binding garante e *sinaliza claramente para o programador* que seu valor nunca vai mudar. Código subseqüente pode assim fazer suposições mais fortes sobre seu uso. 29 | 30 | Torna-se mais fácil raciocinar sobre o código. Se você tivesse usado `var` enquanto supondo que o valor nunca muda, teria que verificar manualmente isso. 31 | 32 | Assim, sempre que você vir um identificador `var` sendo usado, suponha que ele vai mudar e se pergunte o porquê. 33 | 34 | #### Retorno e sair mais cedo 35 | 36 | Quando você tem que atender a certos critérios para continuar a execução, tente sair o mais cedo possível. Assim, em vez disto: 37 | 38 | ```swift 39 | if n.isNumber { 40 |     // Use n aqui 41 | } else { 42 |     return 43 | } 44 | ``` 45 | 46 | use isto: 47 | ```swift 48 | guard n.isNumber else { 49 |     return 50 | } 51 | // Use n aqui 52 | ``` 53 | 54 | Você também pode fazer isso com uma declaração `if`, mas é preferível usar `guard` porque uma declaração `guard` sem `return`, `break` ou `continue` produz um erro de compilação. Logo, a saída é garantida. 55 | 56 | #### Evite usar _Unwrapping_ forçado de Opcionais 57 | 58 | Se você tem um identificador `foo` do tipo `FooType?` ou `FooType!`, se possível não use unwrapping forçado para chegar ao valor subjacente (`foo!`). Em vez de forçar, é preferível: 59 | 60 | ```swift 61 | if let foo = foo { 62 |     // Use o valor de `foo` unwrapped aqui 63 | } else { 64 |     // Se necessário, tratar o caso em que o opcional é nil 65 | } 66 | ``` 67 | 68 | Alternativamente, você pode querer usar encadeamento de opcionais em alguns desses casos, por exemplo: 69 | 70 | ```swift 71 | // Chamar a função se `foo` não é nil. Se `foo` é nil, ignorar que já tentou fazer a chamada 72 | foo?.callSomethingIfFooIsNotNil () 73 | ``` 74 | 75 | _Justificativa:_ Uso explícito de `if let`-binding para opcionais resulta em código mais seguro. _Unwrapping_ forçado é mais propenso a causar erros em tempo de execução. 76 | 77 | #### Evite usar Opcionais _Unwrapped_ Implicitamente 78 | 79 | Sempre que possível, use `let foo: FooType?` ao invés de `let foo:FooType!` se `foo` pode ser `nil` (Note-se que, em geral, `?` pode ser usado ao invés de `!`). 80 | 81 | _Justificativa:_ Opcionais explícitos resultam em código mais seguro. Opcionais _unwrapped_ implicitamente têm o potencial de produzir erros em tempo de execução. 82 | 83 | #### Prefira _getters_ implícitos nas propriedades e _subscripts_ somente leitura. 84 | 85 | Quando possível, omita a palavra-chave `get` em propriedades somente-leitura computadas automaticamente e _subscripts_ somente leitura. 86 | 87 | Então, escreva assim: 88 | 89 | ```swift 90 | var myGreatProperty: Int { 91 | return 4 92 | } 93 | 94 | subscript(index: int) -> T { 95 |     return objects[index] 96 | } 97 | ``` 98 | 99 | ... e não assim: 100 | 101 | ```swift 102 | var myGreatProperty: Int { 103 | get { 104 | return 4 105 | } 106 | } 107 | 108 | subscript(index: int) -> T { 109 |     get { 110 |         return objects[index] 111 |     } 112 | } 113 | ``` 114 | 115 | _Justificativa:_ A intenção e o significado da primeira versão são claros e resultam em menos código. 116 | 117 | #### Sempre especifique o controle de acesso explicitamente para as definições de nível superior 118 | 119 | Funções, tipos e variáveis de nível superior devem sempre ter especificadores de controle de acesso explícitos: 120 | 121 | ```swift 122 | public var whoopsGlobalState: Int 123 | internal struct TheFez {} 124 | private func doTheThings(things: [Thing]) {} 125 | ``` 126 | 127 | No entanto, as definições dentro destes podem deixar o controle de acesso implícito, onde apropriado: 128 | 129 | ```swift 130 | internal struct TheFez { 131 | var owner: Person = Joshaber() 132 | } 133 | ``` 134 | 135 | _Justificativa:_ É raro que definições de nível superior sejam especificamente `internal` e ser explícito garante que essa decisão só é tomada de forma pensada. Dentro de uma definição, reutilizar o mesmo especificador de controle de acesso é duplicação de esforço e o padrão é geralmente razoável. 136 | 137 | #### Ao especificar um tipo, sempre associar os dois pontos (`:`) ao identificador 138 | 139 | Ao especificar o tipo de um identificador, coloque sempre os dois pontos imediatamente 140 | após o identificador, seguido por um espaço e, em seguida, o nome do tipo. 141 | 142 | ```swift 143 | classe SmallBatchSustainableFairtrade: Coffee {...} 144 | 145 | let timeToCoffee: NSTimeInterval = 2 146 | 147 | func makeCoffee (tipo: CoffeeType) -> Coffee {...} 148 | ``` 149 | 150 | _Justificativa:_ O especificador de tipo diz algo sobre o _identificador_ e deve ser posicionado junto a ele. 151 | 152 | Além disso, ao especificar o tipo de um dicionário, sempre coloque os dois pontos imediatamente após o tipo da chave, seguido por um espaço e, em seguida, o tipo de valor. 153 | 154 | ```swift 155 | let capitals: [Country: City] = [ Sweden: Stockholm ] 156 | ``` 157 | 158 | #### Somente se refira a `self` explicitamente quando necessário 159 | 160 | Ao acessar propriedades ou métodos em `self`, deixe a referência ao `self` implícita por padrão: 161 | 162 | ```swift 163 | private class History { 164 | var events: [Event] 165 | 166 | func rewrite () { 167 | events = [] 168 | } 169 | } 170 | ``` 171 | 172 | Só inclua a palavra-chave explícita quando isso for requerido pela linguagem-por exemplo, em um closure ou quando há conflito com os nomes de parâmetros: 173 | 174 | ```swift 175 | extension History { 176 | init (events: [Event]) { 177 | self.events = events 178 | } 179 | 180 | var whenVictorious: () -> () { 181 | return { 182 | self.rewrite () 183 | } 184 | } 185 | } 186 | ``` 187 | 188 | _Justificativa:_ Isso faz com que a semântica de captura de `self` se destaque mais em closures e evita a verbosidade em outros lugares. 189 | 190 | #### Prefira `struct` a `class` 191 | 192 | A menos que você necessite de funcionalidade que só pode ser fornecida por uma classe (como identidade ou des-inicializadores), dê preferência a implementar um `struct`. 193 | 194 | Note-se que a herança (por si só) normalmente _não é_ uma boa razão para usar as classes porque o polimorfismo pode ser fornecido por protocolos e reutilização de implementações pode ser fornecida através de composição. 195 | 196 | Por exemplo, esta hierarquia de classes: 197 | 198 | ```swift 199 | class Vehicle { 200 |     let numberOfWheels: Int 201 | 202 |     init (numberOfWheels: int) { 203 |         self.numberOfWheels = numberOfWheels 204 |     } 205 | 206 |     func maximumTotalTirePressure (pressurePerWheel: Float) -> Float { 207 |         return pressurePerWheel * float (numberOfWheels) 208 |     } 209 | } 210 | 211 | class Bycicle: Vehicle { 212 |     init() { 213 |         super.init(numberOfWheels: 2) 214 |     } 215 | } 216 | 217 | class Car: Vehicle { 218 |     init() { 219 |         super.init(numberOfWheels: 4) 220 |     } 221 | } 222 | ``` 223 | 224 | poderia ser refatorada nestas definições: 225 | 226 | ```swift 227 | protocol Vehicle { 228 |     var numberOfWheels: Int {get} 229 | } 230 | 231 | func maximumTotalTirePressure (vehicle: Vehicle, pressurePerWheel: Float) -> Float { 232 |     return pressurePerWheel * float (vehicle.numberOfWheels) 233 | } 234 | 235 | struct Bicycle: Vehicle { 236 |     let numberOfWheels = 2 237 | } 238 | 239 | struct Car: Vehicle { 240 |     let numberOfWheels = 4 241 | } 242 | ``` 243 | 244 | _Justificativa:_ Tipos de valor (ao invés de referência) são mais simples, mais fáceis de raciocinar sobre e se comportam conforme o esperado com a palavra-chave `let`. 245 | 246 | #### Torne classes `final` por padrão 247 | 248 | Classes devem começar como `final` e só podem ser alteradas para permitir subclasses se uma necessidade válida para herança for identificada. Mesmo neste caso, tantas definições quanto possível _dentro_ da classe devem ser `final`, seguindo as mesmas regras. 249 | 250 | _Justificativa:_ A composição é geralmente preferível à herança e espera-se que a _escolha_ de usar herança seja pensada com cuidado. 251 | 252 | #### Omita parâmetros de tipo sempre que possível 253 | 254 | Métodos de tipos parametrizados podem omitir parâmetros de tipo no tipo de recepção quando eles são idênticos aos do receptor. Por exemplo: 255 | 256 | ```swift 257 | struct Composite { 258 | ... 259 | func compose(other: Composite) -> Composite { 260 | return Composite (self, other) 261 | } 262 | } 263 | ``` 264 | 265 | poderia ser reescrita como: 266 | 267 | ```swift 268 | struct Composite { 269 | ... 270 | func compose (other: Composite) -> Composite { 271 | return Composite (self, other) 272 | } 273 | } 274 | ``` 275 | 276 | _Justificativa:_ Omitir parâmetros de tipo redundantes clarifica a intenção e torna óbvio o caso contrário, quando o tipo retornado recebe parâmetros de diferentes tipos. 277 | 278 | #### Use espaços em branco a redor de definições de operador 279 | 280 | Use espaços em branco ao redor de operadores quando defini-los. Ao invés de: 281 | 282 | ```swift 283 | func <|(lhs: Int, rhs: Int) -> Int 284 | func <|<(lhs: A, rhs: A) -> A 285 | ``` 286 | 287 | Escreva: 288 | 289 | ```swift 290 | func <| (lhs: Int, rhs: Int) -> Int 291 | func <|< (lhs: A, rhs: A) -> A 292 | ``` 293 | 294 | _Justificativa:_ Operadores consistem em caracteres de pontuação, o que pode torná-los difíceis de ler quando imediatamente seguidos pela pontuação para uma lista de parâmetros de tipo ou valor. Adicionar o espaço em branco separa os dois mais claramente. 295 | 296 | #### Traduções 297 | 298 | * [中文 版] (https://github.com/Artwalk/swift-style-guide/blob/master/README_CN.md) 299 | * [日本語 版] (https://github.com/jarinosuke/swift-style-guide/blob/master/README_JP.md) 300 | * [한국어판] (https://github.com/minsOne/swift-style-guide/blob/master/README_KR.md) 301 | * [Versión en Español] (https://github.com/antoniosejas/swift-style-guide/blob/spanish/README-ES.md) 302 | * [Versão original em Inglês](https://github.com/github/swift-style-guide/blob/master/README.md) 303 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | A guide to our Swift style and conventions. 2 | 3 | This is an attempt to encourage patterns that accomplish the following goals (in 4 | rough priority order): 5 | 6 | 1. Increased rigor, and decreased likelihood of programmer error 7 | 1. Increased clarity of intent 8 | 1. Reduced verbosity 9 | 1. Fewer debates about aesthetics 10 | 11 | If you have suggestions, please see our [contribution guidelines](CONTRIBUTING.md), 12 | then open a pull request. :zap: 13 | 14 | ---- 15 | 16 | #### Whitespace 17 | 18 | * Tabs, not spaces. 19 | * End files with a newline. 20 | * Make liberal use of vertical whitespace to divide code into logical chunks. 21 | * Don’t leave trailing whitespace. 22 | * Not even leading indentation on blank lines. 23 | 24 | #### Prefer `let`-bindings over `var`-bindings wherever possible 25 | 26 | Use `let foo = …` over `var foo = …` wherever possible (and when in doubt). Only use `var` if you absolutely have to (i.e. you *know* that the value might change, e.g. when using the `weak` storage modifier). 27 | 28 | _Rationale:_ The intent and meaning of both keywords is clear, but *let-by-default* results in safer and clearer code. 29 | 30 | A `let`-binding guarantees and *clearly signals to the programmer* that its value will never change. Subsequent code can thus make stronger assumptions about its usage. 31 | 32 | It becomes easier to reason about code. Had you used `var` while still making the assumption that the value never changed, you would have to manually check that. 33 | 34 | Accordingly, whenever you see a `var` identifier being used, assume that it will change and ask yourself why. 35 | 36 | #### Return and break early 37 | 38 | When you have to meet certain criteria to continue execution, try to exit early. So, instead of this: 39 | 40 | ```swift 41 | if n.isNumber { 42 | // Use n here 43 | } else { 44 | return 45 | } 46 | ``` 47 | 48 | use this: 49 | ```swift 50 | guard n.isNumber else { 51 | return 52 | } 53 | // Use n here 54 | ``` 55 | 56 | You can also do it with `if` statement, but using `guard` is prefered, because `guard` statement without `return`, `break` or `continue` produces a compile-time error, so exit is guaranteed. 57 | 58 | #### Avoid Using Force-Unwrapping of Optionals 59 | 60 | If you have an identifier `foo` of type `FooType?` or `FooType!`, don't force-unwrap it to get to the underlying value (`foo!`) if possible. 61 | 62 | Instead, prefer this: 63 | 64 | ```swift 65 | if let foo = foo { 66 | // Use unwrapped `foo` value in here 67 | } else { 68 | // If appropriate, handle the case where the optional is nil 69 | } 70 | ``` 71 | 72 | Alternatively, you might want to use Swift's Optional Chaining in some of these cases, such as: 73 | 74 | ```swift 75 | // Call the function if `foo` is not nil. If `foo` is nil, ignore we ever tried to make the call 76 | foo?.callSomethingIfFooIsNotNil() 77 | ``` 78 | 79 | _Rationale:_ Explicit `if let`-binding of optionals results in safer code. Force unwrapping is more prone to lead to runtime crashes. 80 | 81 | #### Avoid Using Implicitly Unwrapped Optionals 82 | 83 | Where possible, use `let foo: FooType?` instead of `let foo: FooType!` if `foo` may be nil (Note that in general, `?` can be used instead of `!`). 84 | 85 | _Rationale:_ Explicit optionals result in safer code. Implicitly unwrapped optionals have the potential of crashing at runtime. 86 | 87 | #### Prefer implicit getters on read-only properties and subscripts 88 | 89 | When possible, omit the `get` keyword on read-only computed properties and 90 | read-only subscripts. 91 | 92 | So, write these: 93 | 94 | ```swift 95 | var myGreatProperty: Int { 96 | return 4 97 | } 98 | 99 | subscript(index: Int) -> T { 100 | return objects[index] 101 | } 102 | ``` 103 | 104 | … not these: 105 | 106 | ```swift 107 | var myGreatProperty: Int { 108 | get { 109 | return 4 110 | } 111 | } 112 | 113 | subscript(index: Int) -> T { 114 | get { 115 | return objects[index] 116 | } 117 | } 118 | ``` 119 | 120 | _Rationale:_ The intent and meaning of the first version is clear, and results in less code. 121 | 122 | #### Always specify access control explicitly for top-level definitions 123 | 124 | Top-level functions, types, and variables should always have explicit access control specifiers: 125 | 126 | ```swift 127 | public var whoopsGlobalState: Int 128 | internal struct TheFez {} 129 | private func doTheThings(things: [Thing]) {} 130 | ``` 131 | 132 | However, definitions within those can leave access control implicit, where appropriate: 133 | 134 | ```swift 135 | internal struct TheFez { 136 | var owner: Person = Joshaber() 137 | } 138 | ``` 139 | 140 | _Rationale:_ It's rarely appropriate for top-level definitions to be specifically `internal`, and being explicit ensures that careful thought goes into that decision. Within a definition, reusing the same access control specifier is just duplicative, and the default is usually reasonable. 141 | 142 | #### When specifying a type, always associate the colon with the identifier 143 | 144 | When specifying the type of an identifier, always put the colon immediately 145 | after the identifier, followed by a space and then the type name. 146 | 147 | ```swift 148 | class SmallBatchSustainableFairtrade: Coffee { ... } 149 | 150 | let timeToCoffee: NSTimeInterval = 2 151 | 152 | func makeCoffee(type: CoffeeType) -> Coffee { ... } 153 | ``` 154 | 155 | _Rationale:_ The type specifier is saying something about the _identifier_ so 156 | it should be positioned with it. 157 | 158 | Also, when specifying the type of a dictionary, always put the colon immediately 159 | after the key type, followed by a space and then the value type. 160 | 161 | ```swift 162 | let capitals: [Country: City] = [ Sweden: Stockholm ] 163 | ``` 164 | 165 | #### Only explicitly refer to `self` when required 166 | 167 | When accessing properties or methods on `self`, leave the reference to `self` implicit by default: 168 | 169 | ```swift 170 | private class History { 171 | var events: [Event] 172 | 173 | func rewrite() { 174 | events = [] 175 | } 176 | } 177 | ``` 178 | 179 | Only include the explicit keyword when required by the language—for example, in a closure, or when parameter names conflict: 180 | 181 | ```swift 182 | extension History { 183 | init(events: [Event]) { 184 | self.events = events 185 | } 186 | 187 | var whenVictorious: () -> () { 188 | return { 189 | self.rewrite() 190 | } 191 | } 192 | } 193 | ``` 194 | 195 | _Rationale:_ This makes the capturing semantics of `self` stand out more in closures, and avoids verbosity elsewhere. 196 | 197 | #### Prefer structs over classes 198 | 199 | Unless you require functionality that can only be provided by a class (like identity or deinitializers), implement a struct instead. 200 | 201 | Note that inheritance is (by itself) usually _not_ a good reason to use classes, because polymorphism can be provided by protocols, and implementation reuse can be provided through composition. 202 | 203 | For example, this class hierarchy: 204 | 205 | ```swift 206 | class Vehicle { 207 | let numberOfWheels: Int 208 | 209 | init(numberOfWheels: Int) { 210 | self.numberOfWheels = numberOfWheels 211 | } 212 | 213 | func maximumTotalTirePressure(pressurePerWheel: Float) -> Float { 214 | return pressurePerWheel * Float(numberOfWheels) 215 | } 216 | } 217 | 218 | class Bicycle: Vehicle { 219 | init() { 220 | super.init(numberOfWheels: 2) 221 | } 222 | } 223 | 224 | class Car: Vehicle { 225 | init() { 226 | super.init(numberOfWheels: 4) 227 | } 228 | } 229 | ``` 230 | 231 | could be refactored into these definitions: 232 | 233 | ```swift 234 | protocol Vehicle { 235 | var numberOfWheels: Int { get } 236 | } 237 | 238 | func maximumTotalTirePressure(vehicle: Vehicle, pressurePerWheel: Float) -> Float { 239 | return pressurePerWheel * Float(vehicle.numberOfWheels) 240 | } 241 | 242 | struct Bicycle: Vehicle { 243 | let numberOfWheels = 2 244 | } 245 | 246 | struct Car: Vehicle { 247 | let numberOfWheels = 4 248 | } 249 | ``` 250 | 251 | _Rationale:_ Value types are simpler, easier to reason about, and behave as expected with the `let` keyword. 252 | 253 | #### Make classes `final` by default 254 | 255 | Classes should start as `final`, and only be changed to allow subclassing if a valid need for inheritance has been identified. Even in that case, as many definitions as possible _within_ the class should be `final` as well, following the same rules. 256 | 257 | _Rationale:_ Composition is usually preferable to inheritance, and opting _in_ to inheritance hopefully means that more thought will be put into the decision. 258 | 259 | 260 | #### Omit type parameters where possible 261 | 262 | Methods of parameterized types can omit type parameters on the receiving type when they’re identical to the receiver’s. For example: 263 | 264 | ```swift 265 | struct Composite { 266 | … 267 | func compose(other: Composite) -> Composite { 268 | return Composite(self, other) 269 | } 270 | } 271 | ``` 272 | 273 | could be rendered as: 274 | 275 | ```swift 276 | struct Composite { 277 | … 278 | func compose(other: Composite) -> Composite { 279 | return Composite(self, other) 280 | } 281 | } 282 | ``` 283 | 284 | _Rationale:_ Omitting redundant type parameters clarifies the intent, and makes it obvious by contrast when the returned type takes different type parameters. 285 | 286 | #### Use whitespace around operator definitions 287 | 288 | Use whitespace around operators when defining them. Instead of: 289 | 290 | ```swift 291 | func <|(lhs: Int, rhs: Int) -> Int 292 | func <|<(lhs: A, rhs: A) -> A 293 | ``` 294 | 295 | write: 296 | 297 | ```swift 298 | func <| (lhs: Int, rhs: Int) -> Int 299 | func <|< (lhs: A, rhs: A) -> A 300 | ``` 301 | 302 | _Rationale:_ Operators consist of punctuation characters, which can make them difficult to read when immediately followed by the punctuation for a type or value parameter list. Adding whitespace separates the two more clearly. 303 | 304 | #### Translations 305 | 306 | * [中文版](https://github.com/Artwalk/swift-style-guide/blob/master/README_CN.md) 307 | * [日本語版](https://github.com/jarinosuke/swift-style-guide/blob/master/README_JP.md) 308 | * [한국어판](https://github.com/minsOne/swift-style-guide/blob/master/README_KR.md) 309 | * [Versión en Español](https://github.com/antoniosejas/swift-style-guide/blob/spanish/README-ES.md) 310 | * [Versão em Português do Brasil](https://github.com/fernandocastor/swift-style-guide/blob/master/README-PTBR.md) --------------------------------------------------------------------------------