简体   繁体   English

如何将Scala匿名特征实现转换为Rust?

[英]How to convert a Scala anonymous trait implementation to Rust?

I'm having difficulty converting this Scala trait to Rust 我很难将此Scala特性转换为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))
  }

}

Here is my Rust equivalent 这是我的Rust等价物

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,
}

I am getting: 我正进入(状态:

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

If I add a self reference, I still get the same error: 如果添加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,
}

I am not sure how I can instantiate an anonymous Injection like I am doing in Scala. 我不确定如何像在Scala中那样实例化匿名Injection What would be the idiomatic way of converting this Scala trait to Rust? 将这种Scala特性转换为Rust的惯用方式是什么?

In Rust, traits only describe behavior, not data. 在Rust中,特征仅描述行为,而不是数据。 The compiler tells you your trait is not object-safe because you want to return anything that implements the trait, and that 'anything' has no single canonical known size at compile time. 编译器告诉您,特征不是对象安全的,因为您要返回实现该特征的任何内容,并且“任何内容”在编译时都没有单一的规范已知大小。

You can Box your values to put them on the heap, or use references (which will require some scary lifetime juggling and be quite brittle, but avoid the allocation). 您可以将值Box以将其放在堆上,或使用引用(这将需要一些可怕的生命周期处理,并且非常脆弱,但要避免分配)。 You will also need to return a concrete type from map and contraMap . 您还需要从mapcontraMap返回具体类型。 Look how Rust's Iterator trait does it: It returns a Map which is generic over the original iterator and the function type it maps, wraps both and implements Iterator . 看一下Rust的Iterator特性是如何实现的:它返回一个Map ,该Map在原始Iterator上具有通用性,并且它映射的函数类型,包装二者并实现Iterator

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM