2016-08-25 2 views
1
Scala 2.11.4 

У меня есть следующие чертынеявной функции преобразования в черта с одним методом

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

и класс

class MyClass{ 

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

Теперь я хочу, чтобы вызвать ac следующим образом:

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

Итак, я попытался добавить неявное преобразование в 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) 
    } 
} 

но он отказывается компилировать:

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

Я пришел из Java 8. Есть ли способ сделать такую ​​вещь в Scala?

ответ

3
  1. function2MyTrait должен жить в объекте компаньона:

    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. Это будет уже не нужно в Scala 2.12, так как это позволит с помощью лямбды реализовать MyTrait без прохождения через String => Unit.

+0

На самом деле, просто попробовал, и теперь он отлично компилируется. Но я не сталкивался с сопутствующими объектами для 'trait'. Почему это распространено? Это похоже на то, что мы имеем в Java 8 (статические методы в интерфейсах)? – stella

+2

Да, это похоже на статические методы в интерфейсах. Отличие от Java 8 состоит в том, что это существовало с самого начала (или, по крайней мере, в течение очень долгого времени), поэтому оно более широко используется. Что касается сопутствующих объектов, то нет разницы между классами и чертами. –

+1

Почему это не работает: 'implicit def function2MyTrait (f: String => Unit): MyTrait = new MyTrait {def met = f}' Как я читал это, создается анонимный класс, расширяющий MyTrait, в котором метод met реализован. Но компилятор комментирует, что встречался не реализован. – Samar

Смежные вопросы