6090: More style advice r=matklad a=matklad

bors r+\n🤖

Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
bors[bot] 2020-09-29 13:00:36 +00:00 committed by GitHub
commit e315fd9bb0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -197,6 +197,43 @@ fn frobnicate(walrus: Option<Walrus>) {
} }
``` ```
Avoid preconditions that spawn function boundaries:
```rust
// Good
fn string_literal_contents(s: &str) -> Option<&str> {
if s.starts_with('"') && s.ends_with('"') {
Some(&s[1..s.len() - 1])
} else {
None
}
}
fn foo() {
let s: &str = ...;
if let Some(contents) = string_literal_contents(s) {
}
}
// Not as good
fn is_string_literal(s: &str) -> Option<&str> {
s.starts_with('"') && s.ends_with('"')
Some()
}
fn foo() {
let s: &str = ...;
if is_string_literal(s) {
let contents = &s[1..s.len() - 1];
}
}
```
In the "Not as good" version, the precondition that `1` is a valid char boundary is checked in `is_string_literal` and utilized in `foo`.
In the "Good" version, precondition check and usage are checked in the same block, and then encoded in the types.
# Early Returns # Early Returns
Do use early returns Do use early returns
@ -271,6 +308,21 @@ if words.len() != 2 {
} }
``` ```
If allocation is inevitable, let the caller allocate the resource:
```rust
// Good
fn frobnicate(s: String) {
...
}
// Not as good
fn frobnicate(s: &str) {
let s = s.to_string();
...
}
```
# Avoid Monomorphization # Avoid Monomorphization
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*. 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*.