Once you define a variable in Cairo, you cannot change it because in Cairo, unlike other languages, variables are defined as immutable. To change a simple variable and print it to the terminal, let's start a project called variables scarb and use the following code:


use debug::PrintTrait; 
fn main() {    
let x = 15;    
x.print();    
x = 20;    
x.print(); 
}


When we run this code with the command scarb cairo-run we get the following error:


error: Cannot assign to an immutable variable.
  --> variables.cairo:5:5    
x = 20;    
^****^ Error: failed to compile: variables.cairo


This error indicates that the value  x is immutable and you cannot assign a second value. To define variables as mutable in Cairo, you can add the keyword  mut  to the left of the variable. Let's make this change using the code below:


use debug::PrintTrait; 
fn main() {   
   let mut x = 15;   
   x.print();   
   x = 20;   
   x.print(); 
}


This way we can change the value of the variable and get the result we want.


Constants


Constants, like variables, cannot be changed, but unlike variables, constants cannot use the keyword mut and are defined with const  instead of let . Here is an example of a constant variable:


const ONE_HOUR_IN_SECONDS: u32 = 21000;


In Cairo, constants are named with capital letters and an underscore between two words.


Shadowing


Shadowing refers to the case of two variables defined with the same name, where the last variable defined overshadows the first variable defined. Let's illustrate this with the following example:


use debug::PrintTrait;
fn main() {
  let x = 5;
  let x = x + 1;
  {
    let x = x * 2;
     
    x.print()
  }
   
  x.print();
}


In this code, the variable x is first assigned the value 5. Then, with the expression let x = x + 1 a new variable x is created by taking the original value of x and adding  1 to it, and this new value of x becomes  6. Then, in the inner scope created by the curly brackets, the variable let x = x * 2 is once again shadowed by the expression  x. A new variable x is created by multiplying the previous value by  2 and this new value of x is  12. When this inner scope ends, the inner shading ends and the importance of  becomes 6 again.


The keyword mut is not used in shadowing. Because the keyword mut allows the same variable to be assigned a different value. In the case of shadowing, however, a new variable with the same name is created with the keyword let and the previous variable is shadowed.


As mentioned earlier, variable shadowing and mutable variables are equivalent at a lower level. When you shadow a variable, the compiler does not complain when you change its type. For example, suppose our program performs a type conversion between the types u64 and felt252.


use debug::PrintTrait;
use traits::Into;
fn main() {
  let x = 2;
  x.print();
  let x: felt252 = x.into(); 
  x.print()
}


The first variable has the u64 type, while the second variable has the felt252 type. Thus shadowing saves us from having to come up with different names like x_u64 and x_felt252 instead we can reuse the simpler x name.


However, if we try to use mut  for this, we get a compile-time error, as shown here:


use debug::PrintTrait;
use traits::Into;
fn main() {
  let mut x: u32 = 2;
  x.print();
  x = 100_felt252;
  x.print()
}


The error says that we expected a u64 (original type) but we got a different type:


$ scarb cairo-run
error: Unexpected argument type. Expected: "core::integer::u32", found: "core::felt252".
 --> lib.cairo:9:9
  x = 100_felt252;
    ^*********^

Error: failed to compile: src/lib.cairo