将所有权移至 std::io::Chain

Moving ownership to a std::io::Chain

我有一个 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 是针对切片而不是数组实现的,不知何故我的数组在这里衰减为切片。
但是,当我将 return 类型的数组更改为切片并为其赋予显式生命周期时,如下所示:

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 以便我可以 return 它? [u8] 是不是根本行不通?

因为 Read 是为 &'_ [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()));
}

参见:

  • Is there any way to return a reference to a variable created in a function?