使用 Vec<u8> 模拟文件 Write
Using a Vec<u8> to mock file Write
我的函数签名是:
fn write_header(source_pkey: PublicKey, target_pkey: PublicKey, nonce: Nonce,
mut output: &mut Box<&mut dyn Write>) -> anyhow::Result<()> {
我正在尝试使用 Vec<u8>
模拟文件来测试它:
#[test]
fn test_write_header() {
let mut vec = Vec::<u8>::new();
let mut out = Box::new(&mut vec);
write_header(
PublicKey([1u8; 32]),
PublicKey([2u8; 32]),
Nonce([3u8; 24]),
&mut out
).unwrap();
assert_eq!(out.len(), 104);
}
但我收到错误消息:
error[E0308]: mismatched types
--> src/encrypt.rs:45:13
|
45 | &mut out
| ^^^^^^^^ expected trait object `dyn std::io::Write`, found struct `Vec`
|
= note: expected mutable reference `&mut Box<&mut dyn std::io::Write>`
found mutable reference `&mut Box<&mut Vec<u8>>
我正在使用 dyn std::io::Write
,因为我需要此功能在正常操作中接受 File
和 Stdout
,以及 Vec<u8>
进行测试。
我是不是做错了,还是要让编译器相信 Vec<u8>
具有 Write
特性?
更新:
Box
是因为 Sized
问题,如果没有它,这段代码将无法编译。
/// Open the program's output file, or stdout if there is no input file.
/// Note: stdout on Windows only accepts utf8.
pub fn open_output(output: Option<String>) -> anyhow::Result<Box<dyn Write>> {
if let Some(filename) = output {
Ok(Box::new(File::open(&filename)
.context(format!("unable to open '{filename}' for output"))?))
} else {
Ok(Box::new(stdout()))
}
}
有没有办法删除这个 Box
? (对后续问题深表歉意。)
解决方案是将 Box
保持在顶层,因为 main()
不知道 output
是否是 Stdout
、File
或其他。
我已将 write_header
的签名更改为:
fn write_header(source_pkey: PublicKey, target_pkey: PublicKey, nonce: Nonce,
output: &mut dyn Write) -> anyhow::Result<()> {
根据 Fracis Gagné 的建议,解决了原始问题。
根据@FrancisGagne 的评论,您可以直接使用 &mut dyn Write
,然后传递 &mut vec
:
use anyhow; // 1.0.52
use std::io::Write;
fn write_header(
source_pkey: (),
target_pkey: (),
nonce: (),
mut output: &mut dyn Write,
) -> anyhow::Result<()> {
output.write(&[1])?;
anyhow::Ok(())
}
#[test]
fn test_write_header() {
let mut vec = Vec::<u8>::new();
write_header(
(),
(),
(),
&mut vec
).unwrap();
assert_eq!(vec.len(), 1);
}
也可以使用impl Write
作为输入参数。这很好,因为您实际上可以使您的函数适用于实现 Write
本身的任何东西:
fn write_header(
source_pkey: (),
target_pkey: (),
nonce: (),
mut output: impl Write,
) -> anyhow::Result<()> {
output.write(&[1])?;
anyhow::Ok(())
}
我的函数签名是:
fn write_header(source_pkey: PublicKey, target_pkey: PublicKey, nonce: Nonce,
mut output: &mut Box<&mut dyn Write>) -> anyhow::Result<()> {
我正在尝试使用 Vec<u8>
模拟文件来测试它:
#[test]
fn test_write_header() {
let mut vec = Vec::<u8>::new();
let mut out = Box::new(&mut vec);
write_header(
PublicKey([1u8; 32]),
PublicKey([2u8; 32]),
Nonce([3u8; 24]),
&mut out
).unwrap();
assert_eq!(out.len(), 104);
}
但我收到错误消息:
error[E0308]: mismatched types
--> src/encrypt.rs:45:13
|
45 | &mut out
| ^^^^^^^^ expected trait object `dyn std::io::Write`, found struct `Vec`
|
= note: expected mutable reference `&mut Box<&mut dyn std::io::Write>`
found mutable reference `&mut Box<&mut Vec<u8>>
我正在使用 dyn std::io::Write
,因为我需要此功能在正常操作中接受 File
和 Stdout
,以及 Vec<u8>
进行测试。
我是不是做错了,还是要让编译器相信 Vec<u8>
具有 Write
特性?
更新:
Box
是因为 Sized
问题,如果没有它,这段代码将无法编译。
/// Open the program's output file, or stdout if there is no input file.
/// Note: stdout on Windows only accepts utf8.
pub fn open_output(output: Option<String>) -> anyhow::Result<Box<dyn Write>> {
if let Some(filename) = output {
Ok(Box::new(File::open(&filename)
.context(format!("unable to open '{filename}' for output"))?))
} else {
Ok(Box::new(stdout()))
}
}
有没有办法删除这个 Box
? (对后续问题深表歉意。)
解决方案是将 Box
保持在顶层,因为 main()
不知道 output
是否是 Stdout
、File
或其他。
我已将 write_header
的签名更改为:
fn write_header(source_pkey: PublicKey, target_pkey: PublicKey, nonce: Nonce,
output: &mut dyn Write) -> anyhow::Result<()> {
根据 Fracis Gagné 的建议,解决了原始问题。
根据@FrancisGagne 的评论,您可以直接使用 &mut dyn Write
,然后传递 &mut vec
:
use anyhow; // 1.0.52
use std::io::Write;
fn write_header(
source_pkey: (),
target_pkey: (),
nonce: (),
mut output: &mut dyn Write,
) -> anyhow::Result<()> {
output.write(&[1])?;
anyhow::Ok(())
}
#[test]
fn test_write_header() {
let mut vec = Vec::<u8>::new();
write_header(
(),
(),
(),
&mut vec
).unwrap();
assert_eq!(vec.len(), 1);
}
也可以使用impl Write
作为输入参数。这很好,因为您实际上可以使您的函数适用于实现 Write
本身的任何东西:
fn write_header(
source_pkey: (),
target_pkey: (),
nonce: (),
mut output: impl Write,
) -> anyhow::Result<()> {
output.write(&[1])?;
anyhow::Ok(())
}