From b069c1c69a6a3bc3ea3becbec5cc2fd76a5792cd Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 29 Sep 2020 14:42:09 +0200 Subject: More style advice --- docs/dev/style.md | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) (limited to 'docs/dev/style.md') diff --git a/docs/dev/style.md b/docs/dev/style.md index 397e85b35..bcd86fd3f 100644 --- a/docs/dev/style.md +++ b/docs/dev/style.md @@ -197,6 +197,43 @@ fn frobnicate(walrus: Option) { } ``` +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 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 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*. -- cgit v1.2.3