https://play.rust-lang.org/?version=stable&mode=release&edition=2021&gist=9a463c5f8b8ee51ded6cc9602ff0566f
use rand::Rng; // 0.8.4
#[derive(Debug)]
struct A {
a: i32 // a 的类型是 i32,说明是立即求值的,非惰性(否则应为 Box<FnOnce() -> i32>)
}
impl A {
fn new() -> A {
A { a: rand::thread_rng().gen::<i32>() } // 这里应当“编译期求值”、“立即求值”,还是“惰性求值”?
}
}
fn main() {
dbg!(A::new()); // 如果是“编译期求值”或“立即求值”,那这个值应该是固定的
dbg!(A::new()); // 但结果不一致,难道字段`a`是函数?
}
Rust 结构体的字段是如何被执行的?
1
共 8 条评论, 1 页
评论区
写评论和 Copy 没有关系,而是和有没有实现 Drop 有关:
对于没有实现 Drop 的 const 常量引用会表现为 static,而对于实现了 Drop 的 const 常量引用,实际上会在使用的地方独立创建一份拷贝:
--
👇
Freddie Mercury: 是的,看出来了。
对于实现了
Copy
trait的类型,const
都是指向相同的内存地址,对于在堆上的,编译时等于执行了Clone
。--
👇
Bai-Jinlin: const还是有些奇怪的规则的
比如这个你就能看到不同的地址,把String改成i32地址就一样了,所以const其实不是你下面那么用的。
--
👇
Freddie Mercury: 编译时赋值,貌似只能使用
const fn
,但目前这个限制颇多,而且官方文档里明确说明产生随机值这种情况是绝对不可能的。Const functions have various restrictions to make sure that they can be evaluated at compile-time. It is, for example, not possible to write a random number generator as a const function.
我看到一个nightly的module
std::lazy
,里面可以定义一个Lazy
的结构体,通过解引用访问,只执行一次,可能就是楼主想要的功能。但自己试了几把,感觉多了点其它的疑问。。。
是的,看出来了。
对于实现了
Copy
trait的类型,const
都是指向相同的内存地址,对于在堆上的,编译时等于执行了Clone
。--
👇
Bai-Jinlin: const还是有些奇怪的规则的
比如这个你就能看到不同的地址,把String改成i32地址就一样了,所以const其实不是你下面那么用的。
--
👇
Freddie Mercury: 编译时赋值,貌似只能使用
const fn
,但目前这个限制颇多,而且官方文档里明确说明产生随机值这种情况是绝对不可能的。Const functions have various restrictions to make sure that they can be evaluated at compile-time. It is, for example, not possible to write a random number generator as a const function.
我看到一个nightly的module
std::lazy
,里面可以定义一个Lazy
的结构体,通过解引用访问,只执行一次,可能就是楼主想要的功能。但自己试了几把,感觉多了点其它的疑问。。。
const还是有些奇怪的规则的
比如这个你就能看到不同的地址,把String改成i32地址就一样了,所以const其实不是你下面那么用的。
--
👇
Freddie Mercury: 编译时赋值,貌似只能使用
const fn
,但目前这个限制颇多,而且官方文档里明确说明产生随机值这种情况是绝对不可能的。Const functions have various restrictions to make sure that they can be evaluated at compile-time. It is, for example, not possible to write a random number generator as a const function.
我看到一个nightly的module
std::lazy
,里面可以定义一个Lazy
的结构体,通过解引用访问,只执行一次,可能就是楼主想要的功能。但自己试了几把,感觉多了点其它的疑问。。。
编译时赋值,貌似只能使用
const fn
,但目前这个限制颇多,而且官方文档里明确说明产生随机值这种情况是绝对不可能的。Const functions have various restrictions to make sure that they can be evaluated at compile-time. It is, for example, not possible to write a random number generator as a const function.
我看到一个nightly的module
std::lazy
,里面可以定义一个Lazy
的结构体,通过解引用访问,只执行一次,可能就是楼主想要的功能。但自己试了几把,感觉多了点其它的疑问。。。
头一回听到惰性这个词,在rust中除了
literal
,只有static
声明的变量或函数是在编译期计算的,其他的调用和赋值都是在程序运行执行到才会计算。退一步说,哪怕
gen
声明为static
,你调用了两次new
,就调用了2次gen
,2次gen
调用返回的值一定是一样的吗?new 是一个函数,返回一个 A 的值,你返回了 2 个 A, 我看你想表达的是这种:
a 是 i32 类型的值; rand::thread_rng().gen::() 是一个表达式,其结果是 i32 类型的值; 每次调用 rand::thread_rng().gen::() 都会返回一个随机的 i32 类型的值,你调用了2次,结果不同很正常; const function 才是编译期求值;
每次执行new的时候,都会执行一次gen,肯定不一样了