【问题标题】:Scala object extends abstract class/trait, access companion class fieldsScala 对象扩展抽象类/特征,访问伴随类字段
【发布时间】:2017-09-21 22:37:43
【问题描述】:

目前我有以下代码:

case class Foo(text: String, tag: Tag) {...}
object Foo {
    def doSomething(fooSeq: Seq[Foo]) = fooSeq.map(f => f.tag)
    def doSomethingElse() = {...}
}

我想将doSomething 方法移动到一个抽象类/特征中,这样我就可以对标签进行参数化并在以后重用代码。理想情况下,我想做这样的事情:

case class Foo(text: String, tag: Tag) {...}
object Foo extends TraitFoo[Tag] {
    def doSomethingElse() = {...}
}

---------------in another file----------------

trait TraitFoo[T] = {
    def doSomething(fooSeq: Seq[TraitFoo[T]]) = fooSeq.map(f => f.tag)
}

但是,编译器抱怨它无法识别f.tag 内的TraitFoo

我考虑过使用抽象类,但这也会导致问题,因为我的对象 Foo 不需要构造函数。它只需要访问其伴生类中的字段。

【问题讨论】:

    标签: scala abstract-class traits


    【解决方案1】:

    也许您可以将另一个类型参数添加到 TraitFoo 与结构绑定?像这样:

    trait TraitFoo[A, B <: { def tag: A }] {
        def doSomething(fooSeq: Seq[B]): Seq[A] = fooSeq.map(f => f.tag)
    }
    
    case class Foo(text: String, tag: Tag) { ... }
    object Foo extends TraitFoo[Tag, Foo] {
        def doSomethingElse() = { ... }
    }
    

    这将与此基本相同,但不那么冗长/不那么明确:

    trait Tagged[A] {
        def tag: A
    }
    trait TraitFoo[A, B <: Tagged[A]] {
        def doSomething(fooSeq: Seq[B]): Seq[A] = fooSeq.map(f => f.tag)
    }
    
    case class Foo(text: String, tag: Tag) extends Tagged[Tag] { }
    object Foo extends TraitFoo[Tag, Foo] {
        def doSomethingElse() = { }
    }
    

    【讨论】:

    • 但是,如果我想在TraitFoo 中放入多个返回类型不同的方法,那会不会变得非常复杂?
    • 不一定?取决于这些方法的作用以及不同类型的相关性。您还可以将类型参数移动到方法本身,例如trait TraitFoo[A] { def doSomething[B &lt;: { def tag: A }](fooSeq: Seq[B]) ...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-22
    • 2011-05-14
    • 1970-01-01
    • 2018-02-06
    • 1970-01-01
    • 1970-01-01
    • 2011-11-19
    相关资源
    最近更新 更多