4 ms·
Such operations often consume `self` in Rust, resulting in compile time errors: use std::io::{self, *}; fn main() -> io::Result<()> { let mut
by MaulingMonkey 5y ago
Such operations often consume `self` in Rust, resulting in compile time errors:
use std::io::{self, *};
fn main() -> io::Result<()> {
let mut f = std::fs::File::create("asdf.txt")?;
writeln!(f, "asdf")?;
drop(f); // closes asdf.txt
writeln!(f, "asdf")?; // error[E0382]: borrow of moved value: `f`
Ok(())
}
Full diagnostics:
error[E0382]: borrow of moved value: `f`
--> src/main.rs:7:5
|
4 | let mut f = std::fs::File::create("asdf")?;
| ----- move occurs because `f` has type `File`, which does not implement the `Copy` trait
5 | writeln!(f, "asdf")?;
6 | drop(f);
| - value moved here
7 | writeln!(f, "asdf")?;
| ^^^^^^^^^^^^^^^^^^^ value borrowed here after move
|
= note: this error originates in the macro `writeln` (in Nightly builds, run with -Z macro-backtrace for more info)
For more information about this error, try `rustc --explain E0382`.
Of course, a socket timing out or a drive getting unmounted could still yank a handle out from under these APIs, and e.g. C++ still allows for using such zombie objects. There are also ways to help catch such bugs in GCed languages as well (be it ObjectDisposedException making such bugs shallower in C#, or using lambdas/blocks for scopes to turn continued object use into a syntax error:)
# Ruby
File.open("asdf.txt", "w") do |f|
f.write("asdf")
end
f.write("asdf") # f wasn't in scope
Ruby's dynamic nature means this will still fail at runtime, but similar patterns in C# can force compile time syntax errors for use after close.
EDIT: You even see this pattern in Rust, occasionally, to limit reference lifetimes to avoid soundness issues (e.g. all the annoying `.with(...)` blocks you see when using thread_local! : https://doc.rust-lang.org/std/thread/struct.LocalKey.html https://doc.rust-lang.org/std/thread/struct.LocalKey.html ).
- Rochus 5y agoThat's interesting, thanks; with a GC language one would raise a runtime exception instead.