diff options
-rw-r--r-- | docs/dev/style.md | 61 |
1 files changed, 60 insertions, 1 deletions
diff --git a/docs/dev/style.md b/docs/dev/style.md index 44f0956c2..bb99c4855 100644 --- a/docs/dev/style.md +++ b/docs/dev/style.md | |||
@@ -181,6 +181,30 @@ fn frobnicate(walrus: Option<Walrus>) { | |||
181 | } | 181 | } |
182 | ``` | 182 | ``` |
183 | 183 | ||
184 | # Early Returns | ||
185 | |||
186 | Do use early returns | ||
187 | |||
188 | ```rust | ||
189 | // Good | ||
190 | fn foo() -> Option<Bar> { | ||
191 | if !condition() { | ||
192 | return None; | ||
193 | } | ||
194 | |||
195 | Some(...) | ||
196 | } | ||
197 | |||
198 | // Not as good | ||
199 | fn foo() -> Option<Bar> { | ||
200 | if condition() { | ||
201 | Some(...) | ||
202 | } else { | ||
203 | None | ||
204 | } | ||
205 | } | ||
206 | ``` | ||
207 | |||
184 | # Getters & Setters | 208 | # Getters & Setters |
185 | 209 | ||
186 | If a field can have any value without breaking invariants, make the field public. | 210 | If a field can have any value without breaking invariants, make the field public. |
@@ -189,7 +213,7 @@ Never provide setters. | |||
189 | 213 | ||
190 | Getters should return borrowed data: | 214 | Getters should return borrowed data: |
191 | 215 | ||
192 | ``` | 216 | ```rust |
193 | struct Person { | 217 | struct Person { |
194 | // Invariant: never empty | 218 | // Invariant: never empty |
195 | first_name: String, | 219 | first_name: String, |
@@ -231,6 +255,41 @@ if words.len() != 2 { | |||
231 | } | 255 | } |
232 | ``` | 256 | ``` |
233 | 257 | ||
258 | # Avoid Monomorphization | ||
259 | |||
260 | Rust uses monomorphization to compile generic code, meaning that for each instantiation of a generic functions with concrete types, the function is compiled afresh, *per crate*. | ||
261 | This allows for exceptionally good performance, but leads to increased compile times. | ||
262 | Runtime performance obeys 80%/20% rule -- only a small fraction of code is hot. | ||
263 | Compile time **does not** obey this rule -- all code has to be compiled. | ||
264 | For this reason, avoid making a lot of code type parametric, *especially* on the boundaries between crates. | ||
265 | |||
266 | ```rust | ||
267 | // Good | ||
268 | fn frbonicate(f: impl FnMut()) { | ||
269 | frobnicate_impl(&mut f) | ||
270 | } | ||
271 | fn frobnicate_impl(f: &mut dyn FnMut()) { | ||
272 | // lots of code | ||
273 | } | ||
274 | |||
275 | // Not as good | ||
276 | fn frbonicate(f: impl FnMut()) { | ||
277 | // lots of code | ||
278 | } | ||
279 | ``` | ||
280 | |||
281 | Avoid `AsRef` polymorphism, it pays back only for widely used libraries: | ||
282 | |||
283 | ```rust | ||
284 | // Good | ||
285 | fn frbonicate(f: &Path) { | ||
286 | } | ||
287 | |||
288 | // Not as good | ||
289 | fn frbonicate(f: impl AsRef<Path>) { | ||
290 | } | ||
291 | ``` | ||
292 | |||
234 | # Documentation | 293 | # Documentation |
235 | 294 | ||
236 | For `.md` and `.adoc` files, prefer a sentence-per-line format, don't wrap lines. | 295 | For `.md` and `.adoc` files, prefer a sentence-per-line format, don't wrap lines. |