2015-10-24 60 views
1

我試圖勾畫出一個通用的方式來運行根據下面的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,但沒有奏效。我不知道該如何對RW的期望。

我試圖運行一個類似的測試儀功能,直接調用解算器,根本不涉及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); 
} 
+1

請儘量減少代碼 - 它包含很多與問題無關的東西。 –

+0

好的,刪除了相當多的代碼。不知道我是否可以刪除更多,但沒有說清楚。 – Pablo

回答

4

您定義的Problem結構的方式意味着RW被固定在Problem被實例化的時間。在test_solver中,您允許呼叫者指定他們想要的任何R和任何W,但是然後嘗試將特定的Cursor類型傳遞給(problem.solver)

您可以通過兩種方式解決這個問題:

1)不要定義test_solver作爲一個通用的功能。請注意,對於RW,您不需要多次撥打(problem.solver)

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); 
} 
相關問題