我尝试绘制一个运行“问题”的通用方法,根据下面的struct Problem
表示。这些结构包括测试输入/输出和求解器功能。我的目标是通过与标准I / O交互或通过某个测试人员函数来运行这些问题,该函数验证solver
对给定test_input
/ test_output
的有效性。此处的草图仅包含测试仪功能。
当我尝试编译它时,我得到类型不匹配:
problem.rs:43:22: 43:27 error: mismatched types:
expected `R`,
found `std::io::cursor::Cursor<&[u8]>`
(expected type parameter,
found struct `std::io::cursor::Cursor`) [E0308]
problem.rs:43 (problem.solver)(input, &mut output);
^~~~~
problem.rs:43:22: 43:27 help: run `rustc --explain E0308` to see a detailed explanation
problem.rs:43:29: 43:40 error: mismatched types:
expected `&mut W`,
found `&mut std::io::cursor::Cursor<collections::vec::Vec<u8>>`
(expected type parameter,
found struct `std::io::cursor::Cursor`) [E0308]
problem.rs:43 (problem.solver)(input, &mut output);
^~~~~~~~~~~
problem.rs:43:29: 43:40 help: run `rustc --explain E0308` to see a detailed explanation
error: aborting due to 2 previous errors
我希望编译器将Cursor<&[u8]>
作为BufRead
,将Cursor<Vec<u8>>
作为Write
r,但它不起作用。我不知道对R
或W
的期望是什么。
我尝试通过直接调用求解器来运行类似的测试器函数,而根本不涉及Problem
,并且它有效;所以我认为这些错误可能与我调用(problem.solver)(input, &mut output)
的方式有关。除此之外,我不知道。有人可以告诉我这里发生了什么吗?
use std::io::prelude::*;
use problems::Problem;
mod problems {
use std::io::prelude::*;
pub struct Problem<'a, R, W>
where R: BufRead, W: Write
{
test_input: &'a str,
test_output: &'a str,
solver: Box<fn(R, &mut W)>,
}
mod a_problem {
use std::io::prelude::*;
use super::Problem;
pub fn getProblem<'a, R, W>() -> Problem<'a, R, W>
where R: BufRead, W: Write
{
Problem {
test_input: unimplemented!(),
test_output: unimplemented!(),
solver: Box::new(solver),
}
}
fn solver<R, W>(input: R, output: &mut W)
where R: BufRead, W: Write
{
unimplemented!();
}
}
}
fn test_solver<R, W>(problem: Problem<R, W>)
where R: BufRead, W: Write
{
let input = std::io::Cursor::new(problem.test_input.as_bytes());
let mut output = std::io::Cursor::new(Vec::<u8>::new());
(problem.solver)(input, &mut output);
assert_eq!(problem.test_output.as_bytes(), &*output.into_inner());
}
fn main() {
let problem = problems::a_problem::getProblem();
test_solver(problem);
}
答案 0 :(得分:4)
您定义Problem
结构的方式意味着在R
实例化时W
和Problem
是固定的。在test_solver
中,您允许来电者指定他们想要的任何R
和任何W
,但之后您会尝试将特定的Cursor
类型传递给(problem.solver)
。
您可以通过两种方式解决此问题:
1)不要将test_solver
定义为通用函数。请注意,对于(problem.solver)
和R
的不同类型,您不能多次拨打W
。
fn test_solver<'a>(problem: Problem<'a, std::io::Cursor<&'a [u8]>, std::io::Cursor<Vec<u8>>>)
{
let input = std::io::Cursor::new(problem.test_input.as_bytes());
let mut output = std::io::Cursor::new(Vec::<u8>::new());
(problem.solver)(input, &mut output);
assert_eq!(problem.test_output.as_bytes(), &*output.into_inner());
}
2)不要将solver
字段定义为通用字段。让函数采用特征引用。
use std::io::prelude::*;
use problems::Problem;
mod problems {
use std::io::prelude::*;
pub struct Problem<'a>
{
pub test_input: &'a str,
pub test_output: &'a str,
pub solver: Box<fn(&mut BufRead, &mut Write)>,
}
pub mod a_problem {
use std::io::prelude::*;
use super::Problem;
pub fn getProblem<'a>() -> Problem<'a>
{
Problem {
test_input: unimplemented!(),
test_output: unimplemented!(),
solver: Box::new(solver),
}
}
fn solver(input: &mut BufRead, output: &mut Write)
{
unimplemented!();
}
}
}
fn test_solver(problem: Problem)
{
let mut input = std::io::Cursor::new(problem.test_input.as_bytes());
let mut output = std::io::Cursor::new(Vec::<u8>::new());
(problem.solver)(&mut input, &mut output);
assert_eq!(problem.test_output.as_bytes(), &*output.into_inner());
}
fn main() {
let problem = problems::a_problem::getProblem();
test_solver(problem);
}