2017-09-11 75 views
0

我有困难的转换这斯卡拉特质生锈如何将斯卡拉匿名特质实现转换为Rust?

trait Inject[A, B] { 
    self => 

    def inject(input: A): B 

    def project(input: B): Try[A] 

    def contraMap[AA](inj: Inject[AA, A]): Inject[AA, B] = new Inject[AA, B] { 
    override def inject(input: AA) = self.inject(inj.inject(input)) 

    override def project(input: B) = self.project(input).flatMap(i => inj.project(i)) 
    } 

    def map[BB](inj: Inject[B, BB]): Inject[A, BB] = new Inject[A, BB] { 
    override def inject(input: A) = inj.inject(self.inject(input)) 

    override def project(input: BB) = inj.project(input).flatMap(i => self.project(i)) 
    } 

} 

这里是我的防锈相当于

pub trait Injection<A, B> { 
    fn inject(input: A) -> B; 
    fn project(input: B) -> Result<A, InjectionError>; 
    fn contraMap<AA>(input: Injection<AA, A>) -> Injection<AA, B>; 
    fn map<BB>(input: Injection<B, BB>) -> Injection<A, BB>; 
} 

pub struct InjectionError { 
    msg: String, 
} 

我越来越:

error[E0038]: the trait `Injection` cannot be made into an object 
--> src/main.rs:4:5 
    | 
4 |  fn contraMap<AA>(input: Injection<AA, A>) -> Injection<AA, B>; 
    |  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Injection` cannot be made into an object 
    | 
    = note: method `inject` has no receiver 
    = note: method `project` has no receiver 
    = note: method `contraMap` has no receiver 
    = note: method `map` has no receiver 

如果我添加一个self参考,我仍然得到相同的错误:

pub trait Injection<A, B> { 
    fn inject(&self, input: A) -> B; 
    fn project(&self, input: B) -> Result<A, InjectionError>; 
    fn contraMap<AA>(&self, input: Injection<AA, A>) -> Injection<AA, B>; 
    fn map<BB>(&self, input: Injection<B, BB>) -> Injection<A, BB>; 
} 

pub struct InjectionError { 
    msg: String, 
} 

我不知道如何实例化一个匿名Injection就像我在Scala中做的那样。将Scala特征转换为Rust的惯用方式是什么?

+2

请制作[MCVE],您可以使用Rust Playground来做到这一点。您可能还想在Google上搜索您的错误消息,它已经在计算器上出现了很多次。 –

+1

当前,您定义的'Injection'包含四个**静态函数**。如果你想定义方法,你需要指定'self'参数。我会建议(重新)阅读方法语法的章节:https://doc.rust-lang.org/book/second-edition/ch05-03-method-syntax.html –

+2

通常,你不会有很容易试图直接将Scala翻译成Rust。通过解释你正在努力达成的目标开始会容易得多。 –

回答

0

在锈中,性状只描述行为,而不描述数据。编译器告诉你,你的特征不是对象安全的,因为你想要返回实现特征的任何东西,而且在编译时这个“任何东西”没有单一规范的已知大小。

你可以Box把你的价值放在堆上,或者使用引用(这将需要一些可怕的终生杂耍,并且相当脆弱,但是避免分配)。您还需要返回mapcontraMap的具体类型。查看Rust的Iterator特征如何实现它:它返回一个Map,它在原始迭代器和它映射的函数类型上是泛型的,包装并实现Iterator