Using variables

To get default folder I use such construction:

std::env::current_dir() ?

It works very well.

But, when I try to use a variable

let curr_dir :path = std::env::current_dir()? ;

I get immediately a lot Rust-specific errors from compiler: borrowing problems, used moved (use Copy), etc..

Q.: Are there some benefits of using variables ?

In addition to posting the actual error messages, it would be helpful if you...

But, the short answer to the question is "yes".

3 Likes

It looks like you may have just used the wrong annotation for the type. current_dir() returns a Result<PathBuf, _> not a Path. (Also, Path is unsized (like str), so it can't be returned; you'll generally see &Path not Path, just like you generally see &str and not str.)

Maybe you ended up with a PathBuf, passed it somewhere that expected a P: AsRef<Path>[1] and lost ownership of it, and then tried to use curr_dir again afterwards. If so, pass &curr_dir instead of curr_dir. If you passed it to something that requires PathBuf, pass curr_dir.clone() instead.

If you're storing these in your own data structures, store PathBuf, not &Path.

These are just somewhat wild guesses at the errors you may be encountering.

Yes. There are also benefits to functions, operators, data structures, and traits.

They are also so fundamental to programming in Rust that it's hard to say much more.


  1. a bad but common, or even idiomatic, API ↩ī¸Ž

5 Likes

I mean in this situation, not globally in programming world.. :slight_smile:

You haven't shared enough for anyone to understand your actual situation.

2 Likes
error[E0382]: borrow of moved value: `my_dir`
--> src\main.rs:142:58
128 |     let my_dir = env::current_dir()? ;   
    |         ------ move occurs because `my_dir` has type `PathBuf`, which does not implement the `Copy` trait 
129 | 
130 |     if let Ok(my_entries) = std::fs::read_dir( my_dir /* std::env::current_dir()?  */) { 
    |                                                  ------ value moved here 
  ...   
142 |         std::path:: Path::new(   std::path:: Path::new(  & my_dir/*  std::env::current_dir()?  */   )/* . file. . .
      |                                                          ^^^^^^^^ value borrowed here after move
      |                                                                                                                   
help: consider cloning the value if the performance cost is acceptable 
     | 
 130 |     if let Ok(my_entries) = std::fs::read_dir( my_dir.clone() /* std::env::current_dir()?  */) {
     |                                                      ++++++++  

In the first use case you pass the var to a function, and it gets moved there, inside, and isn't available anymore in this scope, that you show. This is fundamental feature of Rust, ownership and moving.

In this case, you can add a ref in the first use so that it stays -- the read_dir accepts anything that can become a reference to Path.

Playground

fn myfn() -> Result<(), Box<dyn std::error::Error>> {
    let my_dir = std::env::current_dir().unwrap();
    if let Ok(my_entries) = std::fs::read_dir( &my_dir) {
        println!("fine!");
    };
    let p = std::path:: Path::new(  & my_dir);
    Ok(())
}
2 Likes

Thanx.
Why when I use

std::env::current_dir()

(instead of the variable) the compiler keeps silence?
So. have I to use variables?
Maybe, with variables Rust works faster or ...
This is my main question..

It's unclear which way you use read_dir() that the compiler is silent. Modify this example in Playground and post a link here, so we could understand.

If you make 2 calls to read_dir, it gets executed twice, doing two calls to the OS. With a var, you do only one call to the OS, save the result your var, and then give it to both function calls. In your case the difference in negligible, but if the call would have taken several seconds, you'd clearly notice the difference.

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.