Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Const variable returns two different values

Tags:

rust

Today I did some tests on the nightly module std::lazy. It works well in local variable. However, when I defined a const variable, it gave me two different values. Seems the Colsure is called multiple times.

#![feature(once_cell)]
use rand::Rng; // 0.8.4
use std::lazy::Lazy;

const CONST_LAZY: Lazy<i32> = Lazy::new(|| rand::thread_rng().gen::<i32>());

fn main() {
    let local_lazy: Lazy<i32> = Lazy::new(|| rand::thread_rng().gen::<i32>());
    println!("{}", *local_lazy); // -1475423855
    println!("{}", *local_lazy); // -1475423855

    println!("{}", *CONST_LAZY); // 1975106939
    println!("{}", *CONST_LAZY); // -1848043613
}
like image 385
Rusty Spotted Avatar asked Dec 15 '21 08:12

Rusty Spotted


People also ask

Can a JavaScript function return two values?

Summary. JavaScript doesn't support functions that return multiple values. However, you can wrap multiple values into an array or an object and return the array or the object.

Can we return 2 values from a function in TypeScript?

To return multiple values from a function in TypeScript, group the values in an array and return the array, e.g. return [myValue1, myValue2] as const . You can then destructure and use the values the function returns. Copied! We declared a function that returns multiple values by grouping them in an array.

How do you return two variables?

If you need to keep the two variables separated, you can place them into an array like so: function test(){ var h = "Hello"; var w = "World"; var hw=[h,w]; return hw; } var test = test(); alert(test);

Can a function return multiple values How?

We can return more than one values from a function by using the method called “call by address”, or “call by reference”. In the invoker function, we will use two variables to store the results, and the function will take pointer type data.


1 Answers

This is my code, can anyone tell me why?

Because you're confusing const and static.

Per the official documentation:

A constant item is an optionally named constant value which is not associated with a specific memory location in the program. Constants are essentially inlined wherever they are used, meaning that they are copied directly into the relevant context when used. This includes usage of constants from external crates, and non-Copy types. References to the same constant are not necessarily guaranteed to refer to the same memory address.

(note that the phrasing of the last sentence indicates consts could be promoted to statics and share a memory address, but there's no guarantee there, and while statics can be inlined it probably should not be observable through safe rust so should mostly be irrelevant).

In essence, your snippet is semantically equivalent to:

#![feature(once_cell)]
use rand::Rng; // 0.8.4
use std::lazy::Lazy;

fn main() {
    let local_lazy: Lazy<i32> = Lazy::new(|| rand::thread_rng().gen::<i32>());
    println!("{}", *local_lazy);
    println!("{}", *local_lazy);

    println!("{}", *Lazy::new(|| rand::thread_rng().gen::<i32>()));
    println!("{}", *Lazy::new(|| rand::thread_rng().gen::<i32>()));
}

That is also why it compiles at all, as Lazy is not thread-safe, and thus an actual global (a static) will not compile as it could be shared between threads.

like image 185
Masklinn Avatar answered Sep 19 '22 18:09

Masklinn