fn main() {
let mut a = 1;
let b = &mut a;
let foo = |state: &mut i32| {
Box::new(state);
};
foo(b);
foo(b);
}
如果把闭包换成自动类型推断的则无法编译,这个是因为什么呢?和reborrow有关系?
fn main() {
let mut a = 1;
let b = &mut a;
let foo = |state| {
Box::new(state);
};
foo(b);
foo(b);
}
1
共 9 条评论, 1 页
评论区
写评论https://gist.github.com/xjkdev/209ab1986a50010857ecf034b71fb70c 这是我的源码和mir,确实在我这边调用是没有不同的。
--
👇
Zhanghailin1995: 我在windows 10下连个mir分别是
--
👇
xjkdev: 奇怪的是在我的电脑上,两者的mir都是这个形式的
即
_8 = move _2;
,并没有_7 = &mut (*_2);
这样的语句。 并且在函数、闭包声明时,我印象中也没有显式地把reference move进函数内的语法吧,这样的不确定性行为似乎违反了rust语法设计的一些基础思想。--
👇
Hyuuko: 确实和 reborrow 有关系,reborrow 不仅仅发生在闭包的参数、函数的参数指定类型的时候。变变量绑定指定类型时也会发生 reborrow:
总之这两种情况都可以触发 reborrow:
&mut i32
&mut *b
作为实参所以你的第二段代码不能编译通过确实是因为没有指定类型,而导致没有进行 reborrow。可以用
rustc --emit=mir .\src\main.rs
命令看一下 MIR例 1 指定类型
发生了 reborrow
例 2 自动类型推断
可以看到未发生 reborrow,b 被 move 进去了
我在windows 10下连个mir分别是
--
👇
xjkdev: 奇怪的是在我的电脑上,两者的mir都是这个形式的
即
_8 = move _2;
,并没有_7 = &mut (*_2);
这样的语句。 并且在函数、闭包声明时,我印象中也没有显式地把reference move进函数内的语法吧,这样的不确定性行为似乎违反了rust语法设计的一些基础思想。--
👇
Hyuuko: 确实和 reborrow 有关系,reborrow 不仅仅发生在闭包的参数、函数的参数指定类型的时候。变变量绑定指定类型时也会发生 reborrow:
总之这两种情况都可以触发 reborrow:
&mut i32
&mut *b
作为实参所以你的第二段代码不能编译通过确实是因为没有指定类型,而导致没有进行 reborrow。可以用
rustc --emit=mir .\src\main.rs
命令看一下 MIR例 1 指定类型
发生了 reborrow
例 2 自动类型推断
可以看到未发生 reborrow,b 被 move 进去了
奇怪的是在我的电脑上,两者的mir都是这个形式的
即
_8 = move _2;
,并没有_7 = &mut (*_2);
这样的语句。 并且在函数、闭包声明时,我印象中也没有显式地把reference move进函数内的语法吧,这样的不确定性行为似乎违反了rust语法设计的一些基础思想。--
👇
Hyuuko: 确实和 reborrow 有关系,reborrow 不仅仅发生在闭包的参数、函数的参数指定类型的时候。变变量绑定指定类型时也会发生 reborrow:
总之这两种情况都可以触发 reborrow:
&mut i32
&mut *b
作为实参所以你的第二段代码不能编译通过确实是因为没有指定类型,而导致没有进行 reborrow。可以用
rustc --emit=mir .\src\main.rs
命令看一下 MIR例 1 指定类型
发生了 reborrow
例 2 自动类型推断
可以看到未发生 reborrow,b 被 move 进去了
确实和 reborrow 有关系,reborrow 不仅仅发生在闭包的参数、函数的参数指定类型的时候。变变量绑定指定类型时也会发生 reborrow:
总之这两种情况都可以触发 reborrow:
&mut i32
&mut *b
作为实参所以你的第二段代码不能编译通过确实是因为没有指定类型,而导致没有进行 reborrow。可以用
rustc --emit=mir .\src\main.rs
命令看一下 MIR例 1 指定类型
发生了 reborrow
例 2 自动类型推断
可以看到未发生 reborrow,b 被 move 进去了
感谢回复,我看看
--
👇
xjkdev: 我找到一个类似的问题:https://github.com/rust-lang/rust/issues/62640
我找到一个类似的问题:https://github.com/rust-lang/rust/issues/62640
我检查了一下,发现类型推断与非类型推断的foo的类型貌似是一模一样的,就连mir中似乎都看不出区别。这可能是一个bug?建议往stackoverflow或github的issues里面发一下。
--
👇
xjkdev: rust的类型推断是会考虑上下文的,所以这么写语法是没有问题的。
这里的问题在于未标注类型的时候,第一个foo(b)似乎将&mut i32当成一个值类型,move进了foo这个闭包的作用域,而不是引用类型的传递。而标注了state的类型时,就是直接按引用传递了。
--
👇
Neutron3529: 定义闭包时本来就是要指定类型的吧
除了iter里面(比如foreach(|x|...)这里可以不指定类型)的闭包可以不指定类型之外,我是真的不知道还有哪个闭包可以不指定类型
rust的类型推断是会考虑上下文的,所以这么写语法是没有问题的。
这里的问题在于未标注类型的时候,第一个foo(b)似乎将&mut i32当成一个值类型,move进了foo这个闭包的作用域,而不是引用类型的传递。而标注了state的类型时,就是直接按引用传递了。
--
👇
Neutron3529: 定义闭包时本来就是要指定类型的吧
除了iter里面(比如foreach(|x|...)这里可以不指定类型)的闭包可以不指定类型之外,我是真的不知道还有哪个闭包可以不指定类型
定义闭包时本来就是要指定类型的吧
除了iter里面(比如foreach(|x|...)这里可以不指定类型)的闭包可以不指定类型之外,我是真的不知道还有哪个闭包可以不指定类型