stella stella - 3 months ago 11
Scala Question

Implicit conversion function to trait with a single method

Scala 2.11.4


I have the following trait

trait MyTrait{
def met(msg: String): Unit
}


and class

class MyClass{

def ac(mt: MyTrait) = {
//do some job
}
}


Now, I want to invoke
ac
as follows:

val myClass = new MyClass
myClass.as((msg: String) => println(msg)) //meaning that just print out Strings to stdout


So, I tried to add implicit conversion to
MyTrait
:

trait MyTrait {
def met(msgString: String): Unit
implicit def function2MyTrait(f: String => Unit): MyTrait = new MyTraitImpl(f)

private[this] class MyTraitImpl(f: String => Unit) extends MyTrait{
override def met(msgString: String): Unit = f(msgString)
}
}


but it refuses to compile:

Error:(16, 89) type mismatch;
found : String => Unit
required: com.test.trace.MyTrait


I came from Java 8. Is there a way to do such a thing in Scala?

Answer
  1. function2MyTrait needs to live in the companion object:

    trait MyTrait {
      def met(msgString: String): Unit
    }
    object MyTrait {
      implicit def function2MyTrait(f: String => Unit): MyTrait = new MyTraitImpl(f)
    
      private[this] class MyTraitImpl(f: String => Unit) extends MyTrait{
        override def met(msgString: String): Unit = f(msgString)
      }
    }
    
  2. This will be no longer be necessary in Scala 2.12, as it'll allow using lambdas to implement MyTrait without going through String => Unit.

Comments