Scala – Make implicit value classes available in another scope

I have a package foo which contains class FStream . The package object of foo defines a few implicit value classes that provide extender methods for FStream . I would like to move these value classes out of the package object and into their own individual files, but I also want them to always be available when I use FStream (or preferably, when I use anything from foo package. Is it possible to accomplish this? I tried putting implicit value classes into other objects, but I can't extend from objects. Tried putting them in classes or traits, but implicit value classes can only be defined in other objects.

foo/FStream.scala

package foo

class FStream {
  def makeFoo(): Unit = ???
}

foo/package.scala

package foo

package object foo {

  // I want to move these definitions into separate files:

  implicit class SuperFoo(val stream: FStream) extends AnyVal {
    def makeSuperFoo(): Unit = ???
  }

  implicit class HyperFoo(val stream: FStream) extends AnyVal {
    def makeHyperFoo(): Unit = ???
  }
} 

bar/usage.scala

package bar

import foo._ // something nice and short that doesn't reference individual value classes

val x: FStream = ???
x.makeSuperFoo() // should work
x.makeHyperFoo() // should work

I recommend you to read the mandatory tutorial first.

My solution is to use FStream 's companion object. So you can just import FStream and get all the functionality. This also uses trait to separate files.

foo/FStream.scala

package foo

class FStream {
  def makeFoo(): Unit = ???
}

// companion provides implicit
object FStream extends FStreamOp

foo/FStreamOp.scala

package foo

// value class may not be a member of another class
class SuperFoo(val stream: FStream) extends AnyVal {
  def makeSuperFoo(): Unit = ???
}

class HyperFoo(val stream: FStream) extends AnyVal {
  def makeHyperFoo(): Unit = ???
}
trait FStreamOp {
  // you need to provide separate implicit conversion
  implicit def makeSuper(stream: FStream) = new SuperFoo(stream)
  implicit def makeHyper(stream: FStream) = new HyperFoo(stream)
}

usage.scala

import foo.FStream

object Main {
  def main(args: Array[String]): Unit = {
    val x: FStream = ???
    x.makeSuperFoo() // should work
    x.makeHyperFoo() // should work
  }
}
链接地址: http://www.djcxy.com/p/78960.html

上一篇: 将可变参数作为另一种类型传递给另一种方法

下一篇: Scala - 使隐式值类在另一个作用域中可用