简体   繁体   English

覆盖Scala中的密封特征

[英]Overriding a sealed trait in Scala

I am using a library that has a sealed trait. 我正在使用一个具有密封特性的库。 I really need to extend this trait. 我真的需要扩展这个特性。

Is there a way (even a dirty one) to bypass that? 有没有办法(甚至是肮脏的)绕过那个?

For a bit of background, this is what I am trying to work around : https://github.com/ReactiveMongo/ReactiveMongo/issues/247 对于一些背景知识,我正在努力解决这个问题: https//github.com/ReactiveMongo/ReactiveMongo/issues/247

Don't extend, include, If you need to consider another option. 不要扩展,包括, 如果您需要考虑另一种选择。

// Foo.scala
sealed trait Foo
case class Foo1(n: Int) extends Foo
case class Foo2(s: String) extends Foo

// Bar.scala
sealed trait Bar
case class BarFoo(foo: Foo) extends Bar
case class Bar3(b: Boolean) extends Bar

And the boilerplate can be reduced by implicit conversion 并且可以通过隐式转换来减少样板

implicit def fooToBar(foo: Foo): Bar = BarFoo(foo)

Or if you want to add new methods to an existing class , use implicit classes: 或者, 如果要向现有类添加新方法 ,请使用隐式类:

// Foo.scala
sealed trait Foo
case class Foo1(n: Int) extends Foo
case class Foo2(s: String) extends Foo

// Quux.scala
// This class be called FooOps or FooExtra, if you like, name is irrelevant
implicit class Quux(foo: Foo) {
  def quux: Boolean = foo match {
    case Foo1(n) => n == 0
    case Foo2(s) => s.isEmpty
  }
}

Then you can use .quux on Foo values: 然后你可以在Foo值上使用.quux

scala> Foo1(2).quux
res1: Boolean = false

scala> Foo2("").quux
res2: Boolean = true

This is about the same as extending, but with even less boilerplate, compare to: 这与扩展大致相同,但更少的样板,与以下内容相比:

case class Quux2(foo: Foo) {
  def quux2: Boolean = foo match {
    case Foo1(n) => n == 0
    case Foo2(s) => s.isEmpty
  }
}

implicit def fooToQuux2(foo: Foo): Quux2 = Quux2(foo)

scala> Foo1(2).quux
res0: Boolean = false

scala> Foo2("").quux
res1: Boolean = true

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

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