rust - 为什么 &i32 有时实现 Unpin,有时不实现?

标签 rust

use std::pin::Pin;

fn main() {
    let val: i32 = 3;

    let val_pin = Pin::new(&val);
    f(val_pin);

    f(Pin::new(&val));
}

fn f(_val: Pin<&dyn TestTrait>) {}

trait TestTrait {}

impl TestTrait for i32 {}

第 9 行 f(Pin::new(&val)); 抛出编译器错误,但第 6 行 let val_pin = Pin::new(&val); 确实如此不是。编译器错误是:

error[E0277]: `dyn TestTrait` cannot be unpinned
   --> src/main.rs:9:7
    |
9   |     f(Pin::new(&val));
    |       ^^^^^^^^ the trait `Unpin` is not implemented for `dyn TestTrait`
    |
    = note: consider using `Box::pin`
note: required by a bound in `Pin::<P>::new`
   --> /usr/lib/rustlib/src/rust/library/core/src/pin.rs:482:23
    |
482 | impl<P: Deref<Target: Unpin>> Pin<P> {
    |                       ^^^^^ required by this bound in `Pin::<P>::new`

因此,似乎特征 Unpin 是在第 6 行中为 &val 实现的,而不是在第 9 行中实现的。这是为什么?

最佳答案

这与类型推断的一些微妙之处有关。

第 6 行的变量被推断为 Pin<&i32>随后会自动向上转换为 Pin<&dyn TestTrait>在第 7 行。您可以通过在第 6 行之后插入以下赋值来检查这一点,这会强制出现编译时错误,显示 my_val 的类型:

let _: () = my_val;
  = note: expected unit type `()`
                found struct `Pin<&i32>`

(附注:如果 my_val 的类型为 (),则此方法不起作用 - 那么分配将会成功!)

相反,当您创建Pin时作为第 9 行的临时值,推断为 Pin<&dyn TestTrait>而不是Pin<&i32> ,和&dyn TestTrait没有实现Unpin默认情况下。

您可以通过显式指定类型参数 T 来解决此问题的Pin<T>成为&i32第 9 行:

f(Pin::<&i32>::new(&val));

您还可以通过指定 TypeTrait 上的界限来解决此问题的Unpin ,这将导致&dyn TestTrait实现Unpin还有:

trait TestTrait: Unpin {}

最后,您还可以通过更改 f 来解决该问题接受Pin<&impl TestTrait>而不是Pin<&dyn TestTrait> :

fn f(_val: Pin<&impl TestTrait>) {}

正如 @KevinReid 所指出的,您还可以指示特征对象必须实现 Unpin ,这是允许的,因为 Unpin没有方法:

fn f(_val: Pin<&(dyn TestTrait + Unpin)>) {}

关于rust - 为什么 &i32 有时实现 Unpin,有时不实现?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73395507/

相关文章:

rust - 如何返回对 RefCell<Option<T>>> 内部数据的引用?

reference - 有什么方法可以避免结构内部的 mut not mut 引用重复代码?

struct - 将 Enum 定义为 Struct(为什么要使用这种语法)

rust - 为什么 atexit 处理程序在访问 stdout 时会出现 panic ?

rust - 在遍历同一 Vec 中另一个元素的字段时改变 Vec 元素的字段

rust - 我如何告诉编译器我的函数像 process::exit() 一样终止了程序?

vector - 是否可以使用迭代器将向量分成 10 个一组?

for-loop - 如何在 vector 的元素上运行 for 循环并更改 for 循环内部和 for 循环外部的向量?

rust - 有没有办法将变量分配给不同的特征实现?

rust - 如何在 Rust 中读取文本文件并读取每行多个值