参数的隐式转换

时间:2018-08-01 04:38:25

标签: scala

我想拥有一个注册回调的类。例如:

class Service {
   def register(hasCallback: A) = {
   }
}

在某个时候,Service会像这样调用回调:

def onEvent(s: String) {
   a.callback(s)
}

这里的窍门是,如果我将String转换为回调函数预先期望的类型,那会很酷。

例如,完整的伪代码将如下所示:

class Service {
    var a: X
    def register(hasCallback: X) {
        a = hasCallback
    }

    def onEvent(s: String) {
        // somehow convert to the type 'a' expects and 
        // bail out early if conversion fails?
        a.callback(s)
    }
}

class A {
}

class EventListenerA {
    def callback(x: A) = {}
}

class B {
}

class EventListenerB {
    def callback(x: B) = {}
}


object Main {
    def main() {
        val s = new Service()
        val x = new EventListenerA()
        s.register(x)
    }
}

2 个答案:

答案 0 :(得分:0)

看起来如下所示工作正常。不确定是否有更简单的方法。

class X(x: Int) {
    def get(): Int = {
        this.x
    }
}

trait FromX[T] {
    def fromX(x: X): T
}

trait CallbackWithX[T] {
    def callback(x: T)
}

class Service {
    def register[T:FromX](hasCallback: CallbackWithX[T]) {
        val x = new X(1)
        val o = implicitly[FromX[T]].fromX(x)
        hasCallback.callback(o)
    }
}

class A(a: Int) {
    def get(): Int = {
        this.a
    }
}
object A {
    implicit object AFromX extends FromX[A] {
        def fromX(x: X): A = {
            new A(x.get + 1)
        }
    }
}

class EventListenerA extends CallbackWithX[A] {
    def callback(a: A) = {
        println(a.get())
    }
}

object Main {
    def main(args: Array[String]): Unit = {
        val s = new Service()
        val a = new EventListenerA()
        s.register(a)
    }
}

答案 1 :(得分:0)

不确定我完全了解您尝试归档的内容,但是如果我理解正确的话:

您的术语看起来不正确。回调通常是从某种类型A到某种类型B的函数。名称hasCallback通常表示它具有类型Boolean。 因此,您需要一些可以通过两种类型(回调的输入和输出)进行参数化的服务,并且可能会这样:

class Service[X, Y] {
  type Callback = X => Y // just an alias, not really required

  private var cb: Callback = _

  def register(callback: Callback): Unit = {
    cb = callback
  }

  def onEvent(e: X): Unit = {
    Option(cb).foreach(_.apply(e)) // Option here is a way to pass case when callback is not set
  }
}

// and usage
val t = (x: Int) => print(s"Callback with $x") // callback function from Int to Unit
val s = new Service[Int, Unit] // Service instance
s.register(t)
s.onEvent(10)