What is scope ? Is `{ ... }` scope?

fn main() {

    let var =   9;

    /* for i in 0..1 */{
        println!( "{var}"   )  ;
    }
}

Why do we "see" var? Does Rust have different kinds of scopes ?

Sure. Just like most other languages out there. Scopes are not unique Rust thing. Wikipedia have pretty decent article which explains how that works in general.

Because it's “in scope”., Scopes can be nested. Your println! would see variables in the most inner block scope ({…}, as you correctly noted), but also function scope (for the main function), global scope (for that particular crate) and so on.

2 Likes

Well, why should we not see it?

2 Likes

Because of {}... Own scope. Own world. Own env.. No?

fn main() {
    let var =   9;
    fn ss(){
        let var2 =   19;
       println!( "{var}" )  ;    //   !!! NOT FOUND
    }
    println!( "{var2}"   )  ;    //   !!! NOT FOUND

    /* for i in 0..1 */{
        // let var = 99;
        println!( "{var}"   )  ;
        println!( "{var2}"  )  ;  //   !!! NOT FOUND
    }
}

If you want to think of it in terms of "environments", perhaps you should look at it this way: Scopes don't "reset the environment", they "inherit from their parent environment".

1 Like

No. Scopes in Rust don't work like that — yet they also don't work like that in most modern languages: C and C++, C# and Go, Java and Python… they all have similar rules (although in Python nested function would have access to var… they are closer to Rust's closures than to Rust's functions).

I don't really know what to suggest here: while Rust looks like a fantastic language for someone to pick as his (or her) first-ever programming language most (all?) Rust tutorials assume that you are familiar with some kind of “normal” language (C, or C++, C# or Go, Java or Javascript, Python or Ruby, etc…) and thus don't need to be told about how scopes work in general (just how they work in Rust as opposed to JavaScript or Python).

As such you wouldn't find a chapter which discussed the scope concept. E.g. Rust by Example includes chapter named scoping rules and naïve reader may try to look there to find out WTH scoping rules are, but… definition is not there. Rather that chapter talks about how to use scopes (which reader, presumably is already familiar with from experience with other language) deal with ownership, borrows, destructors and so on.

1 Like

They don't always do that, that's the issue.

Function scope doesn't capture variables from the enclosing function environment, but does capture types and constants. But it does capture global variables.

It's all very confusing for the newbie, but none of Rust tutorials are written for a newbie: they all assume you know some other language well, just new to Rust.

2 Likes

Ah, yes -- I completely missed fn in fn part of the thread.

Named fn function items have their own scope, but that's special to fn items. Within a function, scopes nest as one would expect (i.e., anything inside a scope is also visible inside its child scopes).

If it worked as you described it, we would be in great trouble. You couldn't, for example, update (or even read) a variable from within a loop, so this wouldn't work:

let mut x = 0;
for i in 0..10 {
    x += i;
}

Would you really expect this to fail? Probably not.

1 Like