├── CONTRIBUTING.md
├── LICENSE
├── README.md
└── README_KR.md
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | If you want to suggest a change or addition that will help accomplish
2 | [the goals](README.md) of this style guide, please open a pull request that:
3 |
4 | 1. Explains the guideline
5 | 1. Demonstrates the guideline with more-or-less valid example code
6 | 1. Justifies the guideline by explaining the rationale behind it
7 |
8 | Just note that all suggestions are open to discussion and debate! :smile:
9 |
--------------------------------------------------------------------------------
/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.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 |
25 | #### Prefer `let`-bindings over `var`-bindings wherever possible
26 |
27 | 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).
28 |
29 | _Rationale:_ The intent and meaning of both keywords is clear, but *let-by-default* results in safer and clearer code.
30 |
31 | A `let`-binding guarantees and *clearly signals to the programmer* that its value is supposed to and will never change. Subsequent code can thus make stronger assumptions about its usage.
32 |
33 | 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.
34 |
35 | Accordingly, whenever you see a `var` identifier being used, assume that it will change and ask yourself why.
36 |
37 | #### Avoid Using Force-Unwrapping of Optionals
38 |
39 | 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.
40 |
41 | Instead, prefer this:
42 |
43 | ```swift
44 | if let foo = foo {
45 | // Use unwrapped `foo` value in here
46 | } else {
47 | // If appropriate, handle the case where the optional is nil
48 | }
49 | ```
50 |
51 | Alternatively, you might want to use Swift's Optional Chaining in some of these cases, such as:
52 |
53 | ```swift
54 | // Call the function if `foo` is not nil. If `foo` is nil, ignore we ever tried to make the call
55 | foo?.callSomethingIfFooIsNotNil()
56 | ```
57 |
58 | _Rationale:_ Explicit `if let`-binding of optionals results in safer code. Force unwrapping is more prone to lead to runtime crashes.
59 |
60 | #### Avoid Using Implicitly Unwrapped Optionals
61 |
62 | 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 `!`).
63 |
64 | _Rationale:_ Explicit optionals result in safer code. Implicitly unwrapped optionals have the potential of crashing at runtime.
65 |
66 | #### Prefer implicit getters on read-only properties and subscripts
67 |
68 | When possible, omit the `get` keyword on read-only computed properties and
69 | read-only subscripts.
70 |
71 | So, write these:
72 |
73 | ```swift
74 | var myGreatProperty: Int {
75 | return 4
76 | }
77 |
78 | subscript(index: Int) -> T {
79 | return objects[index]
80 | }
81 | ```
82 |
83 | … not these:
84 |
85 | ```swift
86 | var myGreatProperty: Int {
87 | get {
88 | return 4
89 | }
90 | }
91 |
92 | subscript(index: Int) -> T {
93 | get {
94 | return objects[index]
95 | }
96 | }
97 | ```
98 |
99 | _Rationale:_ The intent and meaning of the first version is clear, and results in less code.
100 |
101 | #### Always specify access control explicitly for top-level definitions
102 |
103 | Top-level functions, types, and variables should always have explicit access control specifiers:
104 |
105 | ```swift
106 | public var whoopsGlobalState: Int
107 | internal struct TheFez {}
108 | private func doTheThings(things: [Thing]) {}
109 | ```
110 |
111 | However, definitions within those can leave access control implicit, where appropriate:
112 |
113 | ```swift
114 | internal struct TheFez {
115 | var owner: Person = Joshaber()
116 | }
117 | ```
118 |
119 | _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.
120 |
121 | #### When specifying a type, always associate the colon with the identifier
122 |
123 | When specifying the type of an identifier, always put the colon immediately
124 | after the identifier, followed by a space and then the type name.
125 |
126 | ```swift
127 | class SmallBatchSustainableFairtrade: Coffee { ... }
128 |
129 | let timeToCoffee: NSTimeInterval = 2
130 |
131 | func makeCoffee(type: CoffeeType) -> Coffee { ... }
132 | ```
133 |
134 | _Rationale:_ The type specifier is saying something about the _identifier_ so
135 | it should be positioned with it.
136 |
137 | Also, when specifying the type of a dictionary, always put the colon immediately
138 | after the key type, followed by a space and then the value type.
139 |
140 | ```swift
141 | let capitals: [Country: City] = [ Sweden: Stockholm ]
142 | ```
143 |
144 | #### Only explicitly refer to `self` when required
145 |
146 | When accessing properties or methods on `self`, leave the reference to `self` implicit by default:
147 |
148 | ```swift
149 | private class History {
150 | var events: [Event]
151 |
152 | func rewrite() {
153 | events = []
154 | }
155 | }
156 | ```
157 |
158 | Only include the explicit keyword when required by the language—for example, in a closure, or when parameter names conflict:
159 |
160 | ```swift
161 | extension History {
162 | init(events: [Event]) {
163 | self.events = events
164 | }
165 |
166 | var whenVictorious: () -> () {
167 | return {
168 | self.rewrite()
169 | }
170 | }
171 | }
172 | ```
173 |
174 | _Rationale:_ This makes the capturing semantics of `self` stand out more in closures, and avoids verbosity elsewhere.
175 |
176 | #### Prefer structs over classes
177 |
178 | Unless you require functionality that can only be provided by a class (like identity or deinitializers), implement a struct instead.
179 |
180 | 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.
181 |
182 | For example, this class hierarchy:
183 |
184 | ```swift
185 | class Vehicle {
186 | let numberOfWheels: Int
187 |
188 | init(numberOfWheels: Int) {
189 | self.numberOfWheels = numberOfWheels
190 | }
191 |
192 | func maximumTotalTirePressure(pressurePerWheel: Float) -> Float {
193 | return pressurePerWheel * numberOfWheels
194 | }
195 | }
196 |
197 | class Bicycle: Vehicle {
198 | init() {
199 | super.init(numberOfWheels: 2)
200 | }
201 | }
202 |
203 | class Car: Vehicle {
204 | init() {
205 | super.init(numberOfWheels: 4)
206 | }
207 | }
208 | ```
209 |
210 | could be refactored into these definitions:
211 |
212 | ```swift
213 | protocol Vehicle {
214 | var numberOfWheels: Int { get }
215 | }
216 |
217 | func maximumTotalTirePressure(vehicle: Vehicle, pressurePerWheel: Float) -> Float {
218 | return pressurePerWheel * vehicle.numberOfWheels
219 | }
220 |
221 | struct Bicycle: Vehicle {
222 | let numberOfWheels = 2
223 | }
224 |
225 | struct Car: Vehicle {
226 | let numberOfWheels = 4
227 | }
228 | ```
229 |
230 | _Rationale:_ Value types are simpler, easier to reason about, and behave as expected with the `let` keyword.
231 |
232 | #### Make classes `final` by default
233 |
234 | 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.
235 |
236 | _Rationale:_ Composition is usually preferable to inheritance, and opting _in_ to inheritance hopefully means that more thought will be put into the decision.
237 |
238 |
239 | #### Omit type parameters where possible
240 |
241 | Methods of parameterized types can omit type parameters on the receiving type when they’re identical to the receiver’s. For example:
242 |
243 | ```swift
244 | struct Composite {
245 | …
246 | func compose(other: Composite) -> Composite {
247 | return Composite(self, other)
248 | }
249 | }
250 | ```
251 |
252 | could be rendered as:
253 |
254 | ```swift
255 | struct Composite {
256 | …
257 | func compose(other: Composite) -> Composite {
258 | return Composite(self, other)
259 | }
260 | }
261 | ```
262 |
263 | _Rationale:_ Omitting redundant type parameters clarifies the intent, and makes it obvious by contrast when the returned type takes different type parameters.
264 |
265 | #### Use whitespace around operator definitions
266 |
267 | Use whitespace around operators when defining them. Instead of:
268 |
269 | ```swift
270 | func <|(lhs: Int, rhs: Int) -> Int
271 | func <|<(lhs: A, rhs: A) -> A
272 | ```
273 |
274 | write:
275 |
276 | ```swift
277 | func <| (lhs: Int, rhs: Int) -> Int
278 | func <|< (lhs: A, rhs: A) -> A
279 | ```
280 |
281 | _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.
282 |
283 | #### Translations
284 |
285 | * [中文版](https://github.com/Artwalk/swift-style-guide/blob/master/README_CN.md)
286 | * [日本語版](https://github.com/jarinosuke/swift-style-guide/blob/master/README_JP.md)
287 | * [한국어판](https://github.com/minsOne/swift-style-guide/blob/master/README_KR.md)
--------------------------------------------------------------------------------
/README_KR.md:
--------------------------------------------------------------------------------
1 | Swift 스타일과 규칙 안내입니다.
2 |
3 | 다음 목표(대략적인 우선순위)를 이루는 패턴을 장려하려고 합니다:
4 |
5 | 1. 엄격성 증가, 프로그래머 에러의 가능성 감소
6 | 1. 목적의 명확성 증가
7 | 1. 중복 감소
8 | 1. 미학에 대한 논쟁을 줄임
9 |
10 | 만약 제안이 있으면, 우리의 [공헌 정책](CONTRIBUTING.md)를 보고 pull request를 보내주시기 바랍니다. :zap:
11 |
12 | ----
13 |
14 | #### 공백 [원문](https://github.com/github/swift-style-guide#whitespace)
15 |
16 | * 공백이 아닌 탭 사용.
17 | * 파일 끝에 줄 바꿈.
18 | * 코드를 논리 단위로 나누도록 빈 줄을 아낌없이 사용.
19 | * 줄 끝에 공백을 남기지 않기.
20 | * 빈 줄에서 들여쓰기조차 안됨.
21 |
22 |
23 | #### `var` 바인딩보다 `let` 바인딩을 선호 [원문](https://github.com/github/swift-style-guide#prefer-let-bindings-over-var-bindings-wherever-possible)
24 |
25 | 가능하면(그리고 의심스럽더라도) `var foo = …` 보다 `let foo = …`을 사용합니다. 만약에 정말로 사용해야 할때만 `var`을 사용합니다. (즉, 값이 변할 것을 알고 있고, 예를 들면 `weak` 저장 수식어를 사용할 때입니다.)
26 |
27 | _이유:_ 두 키워드의 목적과 의미는 명확하지만, *기본적으로 let*이 더 안전하고 명확한 코드입니다.
28 |
29 | 프로그래머에게 `let`-바인딩은 값이 예상되고, 바뀌지 않을 것임을 보장하고 명확하게 전달합니다. 후속 코드는 변수의 용도를 더 쉽게 추측할 수 있습니다.
30 |
31 | 코드를 더 쉽게 이해하게 됩니다. `var`를 사용하는 동안 값이 변하지 않았음을 가정해가면서, 직접 확인해야 합니다.
32 |
33 | 따라서 `var` 식별자가 사용된 것을 볼 때마다, 값이 변할 것을 가정하고 스스로 왜 그런지 물어볼 것입니다.
34 |
35 | #### 옵셔널의 강제 언래핑 사용 피하기 [원문](https://github.com/github/swift-style-guide#avoid-using-force-unwrapping-of-optionals)
36 |
37 | 타입 `FooType?` 또는 `FooType!`의 `foo` 식별자가 있다면, 강제 언래핑으로 값(`foo!`)를 얻으려고 하지 마세요. 가능하면 말이죠.
38 |
39 | 대신에, 이 방식으로 하세요:
40 |
41 | ```swift
42 | if let foo = foo {
43 | // 여기에서 언래핑된 `foo` 값 사용
44 | } else {
45 | // 여기에 해당하는 경우, 옵셔널이 nil인 경우를 다루세요.
46 | }
47 | ```
48 |
49 | 아니면 예를 들면 일부의 경우에서 Swift의 옵셔널 채이닝을 사용할 수 있습니다:
50 |
51 | ```swift
52 | // `foo`가 nil이 아니라면 함수가 호출됩니다. 만약 `foo`가 nil이라면 함수 호출을 무시합니다.
53 | foo?.callSomethingIfFooIsNotNil()
54 | ```
55 |
56 | _이유:_ 명시적 옵셔널의 `if let`-바인딩 결과로 더 안전한 코드가 됩니다. 강제 언래핑은 런타임 크래시가 발생할 가능성이 많습니다.
57 |
58 | #### 암시적으로 언래핑된 옵셔널 피하기 [원문](https://github.com/github/swift-style-guide#avoid-using-implicitly-unwrapped-optionals)
59 |
60 | 만약에 `foo`가 nil이라면 `let foo: FooType!` 대신 `let foo: FooType?`를 가능하면 사용하세요.(주의, `!` 대신 `?` 사용할 수 있습니다.)
61 |
62 | _이유:_ 명시적 옵셔널이 더 안전한 코드입니다. 암시적으로 언래핑된 옵셔널은 런타임시 크래시의 원인이 될 수 있습니다.
63 |
64 | #### 읽기전용 속성과 서브스크립트에서 암시적 getter 선호 [원문](https://github.com/github/swift-style-guide#prefer-implicit-getters-on-read-only-properties-and-subscripts)
65 |
66 | 가능하면 읽기 전용 계산된 속성과 읽기 전용 서브스크립트에서 `get` 키워드는 생략합니다.
67 |
68 | 그래서 다음과 같이 작성합니다:
69 |
70 | ```swift
71 | var myGreatProperty: Int {
72 | return 4
73 | }
74 |
75 | subscript(index: Int) -> T {
76 | return objects[index]
77 | }
78 | ```
79 |
80 | … 다음과 같이 작성하지 않습니다.
81 |
82 | ```swift
83 | var myGreatProperty: Int {
84 | get {
85 | return 4
86 | }
87 | }
88 |
89 | subscript(index: Int) -> T {
90 | get {
91 | return objects[index]
92 | }
93 | }
94 | ```
95 |
96 | _이유:_ 첫 번째 버전의 목적과 의미가 명확하여 더 적은 코드가 됩니다.
97 |
98 | #### 항상 최상위 수준 정의를 명시적으로 접근 제어 지정 [원문](https://github.com/github/swift-style-guide#always-specify-access-control-explicitly-for-top-level-definitions)
99 |
100 | 최상위 수준 함수, 타입 그리고 변수는 항상 명시적 접근 제어 지정자가 있어야 합니다:
101 |
102 | ```swift
103 | public var whoopsGlobalState: Int
104 | internal struct TheFez {}
105 | private func doTheThings(things: [Thing]) {}
106 | ```
107 |
108 | 그러나 이들 내 정의는 적절한 곳에 암묵적으로 접근 제어를 남길 수 있습니다:
109 |
110 | ```swift
111 | internal struct TheFez {
112 | var owner: Person = Joshaber()
113 | }
114 | ```
115 |
116 | _이유:_ 최상위 수준 정의에서 더욱 명확하게 `internal`이 되는 것과 명시적으로 신중하게 생각하여 결정을 보장하기가 극히 드뭅니다. 정의 내에서 같은 접근 제어 지정자 재사용은 단지 중복되며, 일반적으로 기본값이 합당합니다.
117 |
118 | #### 타입을 지정할 때, 항상 식별자 뒤에 콜론을 연결 [원문](https://github.com/github/swift-style-guide#when-specifying-a-type-always-associate-the-colon-with-the-identifier)
119 |
120 | 식별자의 타입을 지정할 때, 항상 식발자 뒤에 콜론을 바로 붙이고, 공백 다음에 타입 이름이 붙습니다.
121 |
122 | ```swift
123 | class SmallBatchSustainableFairtrade: Coffee { ... }
124 |
125 | let timeToCoffee: NSTimeInterval = 2
126 |
127 | func makeCoffee(type: CoffeeType) -> Coffee { ... }
128 | ```
129 |
130 | _이유:_ 타입 지정자는 _식별자_에 대해서 무언가를 이야기합니다. 그래서 타입 지정자는 식별자와 위치해야 합니다.
131 |
132 | 또한, 딕셔너리의 타입을 지정할 때, 항상 콜론은 키 타입 뒤에 위치해야 하며 공백 다음에 값 타입이 뒤따릅니다.
133 |
134 | ```swift
135 | let capitals: [Country: City] = [ Sweden: Stockholm ]
136 | ```
137 |
138 | #### 필요할 때만 명시적으로 `self` 참조 [원문](https://github.com/github/swift-style-guide#only-explicitly-refer-to-self-when-required)
139 |
140 | self의 속성과 메소드에 접근할 때, `self`를 따로 적지 않습니다.(기본적으로 `self`는 암묵적 참조입니다.):
141 |
142 | ```swift
143 | private class History {
144 | var events: [Event]
145 |
146 | func rewrite() {
147 | events = []
148 | }
149 | }
150 | ```
151 |
152 | 클로저처럼 파라미터명이 충돌일 경우에만 명시적으로 `self` 키워드를 사용합니다.:
153 |
154 | ```swift
155 | extension History {
156 | init(events: [Event]) {
157 | self.events = events
158 | }
159 |
160 | var whenVictorious: () -> () {
161 | return {
162 | self.rewrite()
163 | }
164 | }
165 | }
166 | ```
167 |
168 | _이유:_ 클로저 내에서 `self`의 캡처링 의미를 더 돋보이게 만들고, 다른 곳에서 장황하게 사용하는 것을 피할 수 있게 합니다.
169 |
170 | #### 클래스 보다 구조체를 선호 [원문](https://github.com/github/swift-style-guide#prefer-structs-over-classes)
171 |
172 | 클래스에서만 사용가능한 것들(identity, deinitializer 등)이 필요한 경우가 아니라면, 구조체로 구현하세요.
173 |
174 | 보통은 클래스를 사용하는 이유가, 상속이 (유일한) 이유는 아닙니다. 왜냐하면 다형성은 프로토콜이 제공할 수 있고, 구현의 재사용은 조립(Composition)을 통해서 가능합니다.
175 |
176 | 다음은 클래스 계층 구조 입니다:
177 |
178 | ```swift
179 | class Vehicle {
180 | let numberOfWheels: Int
181 |
182 | init(numberOfWheels: Int) {
183 | self.numberOfWheels = numberOfWheels
184 | }
185 |
186 | func maximumTotalTirePressure(pressurePerWheel: Float) -> Float {
187 | return pressurePerWheel * numberOfWheels
188 | }
189 | }
190 |
191 | class Bicycle: Vehicle {
192 | init() {
193 | super.init(numberOfWheels: 2)
194 | }
195 | }
196 |
197 | class Car: Vehicle {
198 | init() {
199 | super.init(numberOfWheels: 4)
200 | }
201 | }
202 |
203 | ```
204 |
205 | 다음과 같이 프로토콜로 리팩토링되었습니다:
206 |
207 | ```swift
208 | protocol Vehicle {
209 | var numberOfWheels: Int { get }
210 | }
211 |
212 | func maximumTotalTirePressure(vehicle: Vehicle, pressurePerWheel: Float) -> Float {
213 | return pressurePerWheel * vehicle.numberOfWheels
214 | }
215 |
216 | struct Bicycle: Vehicle {
217 | let numberOfWheels = 2
218 | }
219 |
220 | struct Car: Vehicle {
221 | let numberOfWheels = 4
222 | }
223 | ```
224 |
225 | _이유:_ 값 타입은 더 간단하고, `let` 키워드와 함께 예상대로 동작하여 쉽게 이해합니다.
226 |
227 | #### 기본적으로 클래스는 `final`로 작성 [원문](https://github.com/github/swift-style-guide#make-classes-final-by-default)
228 |
229 | 클래스는 `final`로 시작해야 합니다. 상속이 필요하다면 클래스는 서브클래스를 만들도록 할 수 있게 변경합니다. 심지어, 클래스 내 가능한 많은 정의는 `final`이 되어야 하고, 같은 규칙을 따릅니다.
230 |
231 | _이유:_ 일반적으로 구성은 상속을 선호하고, 아마도 상속을 선택하면 결정하는데 좀 더 많은 생각을 해야 합니다.(역자 주 - 상속 구조를 결정하기 위해 고민을 더 해야 한다고 생각됩니다.)
232 |
233 | #### 가능하면 타입 인자 생략하기 [원문](https://github.com/github/swift-style-guide#omit-type-parameters-where-possible)
234 |
235 | 매개 변수가 된 타입의 메소드는 수신자가 같을 때 받는 타입에 타입 매개 변수를 생략할 수 있습니다. 예를 들어:
236 |
237 | ```swift
238 | struct Composite {
239 | …
240 | func compose(other: Composite) -> Composite {
241 | return Composite(self, other)
242 | }
243 | }
244 | ```
245 |
246 | 다음과 같이 작성할 수 있습니다:
247 |
248 | ```swift
249 | struct Composite {
250 | …
251 | func compose(other: Composite) -> Composite {
252 | return Composite(self, other)
253 | }
254 | }
255 | ```
256 |
257 | _이유:_ 중복 타입 매개변수를 생략하려는 목적이 명확합니다. 그리고 반환 타입이 다른 타입 매개변수를 취할 때 명확하게 차이가 나도록 만듭니다.
258 |
259 | #### 연산자 정의에 공백 사용 [원문](https://github.com/github/swift-style-guide#use-whitespace-around-operator-definitions)
260 |
261 | 연산자를 정의할 때 공백을 사용합니다. 다음과 같이 하지 않습니다:
262 |
263 | ```swift
264 | func <|(lhs: Int, rhs: Int) -> Int
265 | func <|<(lhs: A, rhs: A) -> A
266 | ```
267 |
268 | 다음과 같이 작성합니다:
269 |
270 | ```swift
271 | func <| (lhs: Int, rhs: Int) -> Int
272 | func <|< (lhs: A, rhs: A) -> A
273 | ```
274 |
275 | _이유:_ 연산자는 문장부호로 되어 있으며, 타입 또는 값 매개 변수 목록과 붙어 있으면 읽기 어렵습니다. 공백이 추가되어 더 명확해집니다.
276 |
277 | #### 번역
278 |
279 | * [中文版](https://github.com/Artwalk/swift-style-guide/blob/master/README_CN.md)
280 | * [日本語版](https://github.com/jarinosuke/swift-style-guide/blob/master/README_JP.md)
--------------------------------------------------------------------------------