加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

如何在Scala中混合相同特征的不同类型实例?

发布时间:2020-12-16 09:02:54 所属栏目:安全 来源:网络整理
导读:我想以不同的方式检查如何扩展此代码,然后在需要时将这些功能扩展混合在一起. // Initial object algebra interface for expressions: integers and addition trait ExpAlg[E] { def lit(x : Int) : E def add(e1 : E,e2 : E) : E } // An object algebra im
我想以不同的方式检查如何扩展此代码,然后在需要时将这些功能扩展混合在一起.

// Initial object algebra interface for expressions: integers and addition
    trait ExpAlg[E] {
        def lit(x : Int) : E 
        def add(e1 : E,e2 : E) : E
    }

    // An object algebra implementing that interface (evaluation)

    // The evaluation interface
    trait Eval {
        def eval() : Int
    }

    // The object algebra
    trait EvalExpAlg extends ExpAlg[Eval] {
        def lit(x : Int) = new Eval() {
            def eval() = x
        }

        def add(e1 : Eval,e2 : Eval) = new Eval() {
            def eval() = e1.eval() + e2.eval()
        }
    }

    // Evolution 1: Adding subtraction
    trait SubExpAlg[E] extends ExpAlg[E] {
        def sub(e1 : E,e2 : E) : E
    }

    // Updating evaluation:
    trait EvalSubExpAlg extends EvalExpAlg with SubExpAlg[Eval] {
        def sub(e1 : Eval,e2 : Eval) = new Eval() {
            def eval() = e1.eval() - e2.eval()
        }
    }

    // Evolution 2: Adding pretty printing
    trait PPrint {
        def print() : String
    }


    trait PrintExpAlg extends ExpAlg[PPrint] {
      def lit(x: Int) = new PPrint() {
        def print() = x.toString()
      }
      def add(e1: PPrint,e2: PPrint) = new PPrint() {
        def print() = e1.print() + "+" + e2.print()
      }
    }

    trait PrintSubExpAlg extends PrintExpAlg with SubExpAlg[PPrint] {
      def sub(e1: PPrint,e2: PPrint) = new PPrint() {
        def print() = e1.print() + "-" + e2.print()
      }
    }

object OA extends App {

trait Test extends EvalSubExpAlg with PrintSubExpAlg //error
  }

目前我收到的错误是:
“非法继承;特征测试继承特征SubExpAlg的不同类型实例:
?????pack.SubExpAlg [pack.PPrint]和pack.SubExpAlg [pack.Eval]“

我怎么能把两个类型的Eval和PPint放在一个“帽子”下才能被认为是来自同一家族的类型,或者不是一个正确的解决方案,而我可能在两种类型的成员之间存在冲突的继承呢?

编辑

我改变了它,如下所示:
课程操作

// Initial object algebra interface for expressions: integers and addition
    trait ExpAlg {
        type Opr <: Operations
        def lit(x : Int) : Opr 
        def add(e1 : Opr,e2 : Opr) : Opr
    }

    // An object algebra implementing that interface (evaluation)

    // The evaluation interface
    trait Eval extends Operations {
        def eval() : Int
    }

    // The object algebra
    trait EvalExpAlg extends ExpAlg {
        type Opr = Eval
        def lit(x : Int) = new Eval() {
            def eval() = x
        }

        def add(e1 : Eval,e2 : Eval) = new Eval() {
            def eval() = e1.eval() + e2.eval()
        }
    }

    // Evolution 1: Adding subtraction
    trait SubExpAlg extends ExpAlg {
        def sub(e1 : Opr,e2 : Opr) : Opr
    }

    // Updating evaluation:
    trait EvalSubExpAlg extends EvalExpAlg with SubExpAlg {
        def sub(e1 : Eval,e2 : Eval) = new Eval() {
            def eval() = e1.eval() - e2.eval()
        }
    }

    // Evolution 2: Adding pretty printing
    trait PPrint extends Operations {
        def print() : String
    }


    trait PrintExpAlg extends ExpAlg {
      type Opr = PPrint
      def lit(x: Int) = new PPrint() {
        def print() = x.toString()
      }
      def add(e1: PPrint,e2: PPrint) = new PPrint() {
        def print() = e1.print() + "+" + e2.print()
      }
    }

    trait PrintSubExpAlg extends PrintExpAlg with SubExpAlg {
      def sub(e1: PPrint,e2: PPrint) = new PPrint() {
        def print() = e1.print() + "-" + e2.print()
      }
    }

object OA extends App {

class Test extends EvalSubExpAlg
class Test2 extends PrintSubExpAlg

val evaluate = new Test
val print = new Test2
val l1 = evaluate.lit(5)
val l2 = evaluate.lit(4)
val add1 = evaluate.add(l1,l2).eval()
val print1 = print.add(print.lit(5),print.lit(4)).print()

println(print1)
println(add1)
}

我唯一要问的可能是只使用一个Test类并在两种类型的方法之间导航(通过引用这些类型).

解决方法

让我们简化它:

trait Z {val a = 5}
trait K {val a = 6}
trait A[T] { def aa: T}
trait A1 extends A[Z] { def aa = new Z{}}
trait A2 extends A[K] { def aa = new K{}}
scala> class C extends A1 with A2
<console>:12: error: illegal inheritance;
 class C inherits different type instances of trait A:
A[K] and A[Z]

那么,当你这么做时,你期望被称为什么(新的C).aa?如果你真的不在乎,只想访问C里面的那些:

trait A {type T; protected def aa: T}
trait A1 extends A {type T >: Z; protected def aa = new Z{}}
trait A2 extends A {type T >: K; protected def aa = new K{}}

scala> class C extends A1 with A2 {
   override type T = Any
   override protected def aa = ???
   def bbb:Z = super[A1].aa
   def zzz:K = super[A2].aa
}

但我建议选择一些默认方法并从Z继承Z或从Z继承Z,为C#aa提供正常的默认实现.一般来说,这里的问题是scala中的traits适用于mixin和polymorphism,所以你不能只关闭他们的外部世界成员(由于Liskov-Substitution),即使你实际上并不需要自动强制转换为超类型.有关详情,请参见related question.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读