【问题标题】:Moving ownership to a std::io::Chain将所有权转移到 std::io::Chain
【发布时间】:2019-07-23 07:11:15
【问题描述】:

我有一个Reader,我想在其中添加一些字节,从而创建一个Chain。理想情况下,我想这样做:

use std::io::{Chain, Read};

fn thingify<R: Read>(r: R) -> Chain<[u8; 3], R> {
    let mut arr = [1u8, 2u8, 3u8];
    // Modify arr here
    return arr.chain(r);
}

但这会引发编译器错误:

error[E0308]: mismatched types
 --> test.rs:7:12
  |
3 | fn thingify<R: Read>(r: R) -> Chain<[u8; 3], R>
  |                               ----------------- expected `std::io::Chain<[u8; 3], R>` because of return type
...
7 |     return arr.chain(r);
  |            ^^^^^^^^^^^^ expected array of 3 elements, found &[u8]
  |
  = note: expected type `std::io::Chain<[u8; 3], _>`
             found type `std::io::Chain<&[u8], _>`

据我了解,这似乎是因为 Read 是为切片而不是数组实现的,并且不知何故我的数组在这里衰减为切片。
但是当我将返回类型中的数组更改为切片并给它一个明确的生命周期时:

use std::io::{Chain, Read};

fn thingify<'a, R: Read>(r: R) -> Chain<&'a [u8], R> {
    let arr = [1u8, 2u8, 3u8];
    // Modify arr here
    return arr.chain(r);
}

我只是得到另一个编译器错误:

error[E0515]: cannot return value referencing local variable `arr`
  --> test.rs:19:12
   |
19 |     return arr.chain(r);
   |            ---^^^^^^^^^
   |            |
   |            returns a value referencing data owned by the current function
   |            `arr` is borrowed here

如何将我的阵列的所有权转移到Chain 以便我可以归还它? [u8] 根本无法做到这一点吗?

【问题讨论】:

  • 您的第一个想法是正确的,但最后它不会起作用,除非arr 具有静态生命周期,如果它是您的函数的常量值,您可以像这样使用它(Playground)否则这是不可能的,因为arr 将在函数作用域的末尾被删除,arr 的任何引用都将是一个悬空指针。

标签: rust lifetime ownership


【解决方案1】:

因为Read 是针对&amp;'_ [u8] 而不是针对[u8; 3] 实现的,所以编译器会自动将您的数组转换为引用切片。这意味着只要切片存在,只要Chain 存在,您的数组就必须有效。

有几种解决方案,您可以向调用者请求一个可变切片,如果您希望能够对其进行变异,您可以将其设为 static,如果您不这样做,您可以将其设为 const,如果您需要调整它的大小你需要一个Vec,等等......

use std::io::{stdin, Chain, Read};

fn a<R: Read>(arr: &mut [u8; 3], r: R) -> Chain<&[u8], R> {
    arr.copy_from_slice(&[1, 2, 3]);
    arr.chain(r)
}

fn b<R: Read>(r: R) -> Chain<&'static [u8], R> {
    const ARR: [u8; 3] = [1, 2, 3];
    ARR.chain(r)
}

fn main() {
    let mut arr = [0; 3];
    println!("{:?}", a(&mut arr, stdin()));

    println!("{:?}", b(stdin()));
}

见:

【讨论】:

  • 好吧,我最终创建了自己的结构,其中包含 Box&lt;[u8]&gt; 并手动实现 Read。谢谢一堆。 :)
猜你喜欢
  • 1970-01-01
  • 2015-05-16
  • 1970-01-01
  • 2013-08-19
  • 2016-04-15
  • 1970-01-01
  • 1970-01-01
  • 2017-07-20
  • 1970-01-01
相关资源
最近更新 更多