From 35fcae5c14bfb76da4f0a687ede9d258ae357180 Mon Sep 17 00:00:00 2001 From: Alexander Launi Date: Fri, 31 Jul 2020 21:07:10 -0400 Subject: [PATCH] Leverage non-lexical scoping to clean up example in Filesystem and Processes section Non-lexical lifetimes were added in rust 1.31 (2018 edition) and 1.36 (2015 edition) which have been available for over a year (1.36 released 4 July 2019). This small change updates the code sample and removes a comment explaining the use of scoping to assist the borrow checker. The removed comment was helpful to explain the reasoning behind the local scoping, but was ultimately off topic for the section. core::str<_>::trim_right was deprecated in Rust 1.33 and superceded by trim_end(). Update file4.rs, and file5.rs to use trim_end. --- code/file4.rs | 6 ++---- code/file5.rs | 2 +- src/3-filesystem.md | 19 +++++-------------- 3 files changed, 8 insertions(+), 19 deletions(-) diff --git a/code/file4.rs b/code/file4.rs index 398c200..ca0bbd5 100644 --- a/code/file4.rs +++ b/code/file4.rs @@ -10,10 +10,8 @@ fn read_all_lines(filename: &str) -> io::Result<()> { let mut buf = String::new(); let mut stdout = io::stdout(); while reader.read_line(&mut buf)? > 0 { - { - let line = buf.trim_right(); - write!(stdout,"{}\n",line)?; - } + let line = buf.trim_end(); + write!(stdout,"{}\n",line)?; buf.clear(); } diff --git a/code/file5.rs b/code/file5.rs index dea9b49..761a55c 100644 --- a/code/file5.rs +++ b/code/file5.rs @@ -19,7 +19,7 @@ impl Lines { Ok(nbytes) => if nbytes == 0 { None } else { - let line = self.buf.trim_right(); + let line = self.buf.trim_end(); Some(Ok(line)) }, Err(e) => Some(Err(e)) diff --git a/src/3-filesystem.md b/src/3-filesystem.md index 8d0b394..0785577 100644 --- a/src/3-filesystem.md +++ b/src/3-filesystem.md @@ -50,16 +50,14 @@ of strings using `collect`, or print out the line with line numbers using the It isn't the most efficient way to read all the lines, however, because a new string is allocated for each line. It is more efficient to use `read_line`, although more awkward. Note that the returned line includes the linefeed, which -can be removed using `trim_right`. +can be removed using `trim_end`. ```rust let mut reader = io::BufReader::new(file); let mut buf = String::new(); while reader.read_line(&mut buf)? > 0 { - { - let line = buf.trim_right(); - println!("{}", line); - } + let line = buf.trim_end(); + println!("{}", line); buf.clear(); } ``` @@ -68,13 +66,6 @@ This results in far less allocations, because _clearing_ that string does not fr allocated memory; once the string has enough capacity, no more allocations will take place. -This is one of those cases where we use a block to control a borrow. `line` is -borrowed from `buf`, and this borrow must finish before we modify `buf`. Again, -Rust is trying to stop us doing something stupid, which is to access `line` _after_ -we've cleared the buffer. (The borrow checker can be restrictive sometimes. -Rust is due to get 'non-lexical lifetimes', where -it will analyze the code and see that `line` isn't used after `buf.clear()`.) - This isn't very pretty. I cannot give you a proper iterator that returns references to a buffer, but I can give you something that _looks_ like an iterator. @@ -117,7 +108,7 @@ Trim this away, and package up the string slice. Ok(nbytes) => if nbytes == 0 { None // no more lines! } else { - let line = self.buf.trim_right(); + let line = self.buf.trim_end(); Some(Ok(line)) }, Err(e) => Some(Err(e)) @@ -540,7 +531,7 @@ fn shell(cmd: &str) -> (String,bool) { .output() .expect("no shell?"); ( - String::from_utf8_lossy(&output.stdout).trim_right().to_string(), + String::from_utf8_lossy(&output.stdout).trim_end().to_string(), output.status.success() ) }