2016-04-04 23 views
1

我正在學習Rust,並且遇到了涉及閉包的令人煩惱的問題。我已經獲得了許多基本的關閉示例,但現在我已經走出了基本的「加法器」和「調用」示例,事情變得雜亂無章。這是我的代碼,其中工程第一部分:從涉及Rust中的泛型的特徵方法返回閉包

trait TransformationElt<T, F> where F: Fn(T) -> T { 
    fn get_transform(&self) -> Box<F>; 
} 

pub struct AddSome { pub x: i64 } 

impl AddSome { 
    fn the_transform(&self) -> Box<Fn(i64) -> i64> { 
     Box::new(|x: i64| x + 1 as i64) 
    } 
} 

這成功地返回一個堆分配封閉,增加了1,實施我們的AddSome類型。我想AddSome實現TransformationElt,專門爲類型i64

impl<F: Fn(i64) -> i64> TransformationElt<i64, F> for AddSome { 
    fn get_transform(&self) -> Box<F> { 
     Box::new(move |x: i64| x + self.x as i64) 
    } 
} 

經過一番兩輪牛車和嘗試不同的東西,我仍然不能得到它來編譯。我通常得到的錯誤是:

src/lex/math/algebra/groups.rs:31:16: 31:46 error: mismatched types: expected F , found [[email protected]/lex/math/algebra/groups.rs:31:16: 31:46 self:_] (expected type parameter, found closure) [E0308]

如何解決這個看似基本的問題,實現我的「改造」型?

最後一件事 - 我有理由想把事情當作關閉。我打算把它們組合起來,等等,我真的需要更高級的功能。

回答

2

編譯器正在阻止你,因爲你試圖對它撒謊。當我們說謊時,通過程序員看我們是非常好的。

你是怎麼說謊的?你說過「我要編寫一個採用某種任意類型的方法(有一些限制),然後我要返回一個只包含該類型的方框」。您接着進入而不是返回一個傳入的值框;只要編譯器在意,就插入了包裝垃圾。

繼承人一個小例子:

fn wrapper<F>(f: F) -> Box<F> 
    where F: Fn(u8) -> u8 
{ 
    Box::new(|x| f(x) + 1) 
} 

fn main() {} 

你真正想說的是,你將返回的東西,實現了特徵,但沒有描述如何(因爲你不能指定一個閉合)。你與間接做到這一點,一個盒裝特質對象:

fn wrapper<F>(f: F) -> Box<Fn(u8) -> u8> 
    where F: Fn(u8) -> u8 + 'static 
{ 
    Box::new(move |x| f(x) + 1) 
} 

fn main() {} 

高度相關:

  1. Return a closure from a function
  2. Returning a closure from a function
  3. Figuring out return type of closure