【问题标题】:How to pass function of subclass to scala map?如何将子类的功能传递给scala map?
【发布时间】:2018-01-23 20:38:04
【问题描述】:

我正在尝试将带有子类参数的函数传递到地图中(没有成功):

  trait GeneralRequestData
  case class MyRequestData(some: String) extends GeneralRequestData

  val myRequestDataToJsValue = (m: MyRequestData) => Json.obj("a" -> "b")

  val transformers: scala.collection.mutable.Map[String, _ <: GeneralRequestData => JsValue] = new mutable.HashMap()
  transformers.put("myRequestData", myRequestDataToJsValue) // Error:(76, 37) type mismatch; found : myRequestDataToJsValue.type (with underlying type MyRequestData => play.api.libs.json.JsObject) required: _$2 transformers.put("myRequestData", myRequestDataToJsValue)

但我得到了错误:

错误:(76, 37) 类型不匹配;找到:myRequestDataToJsValue.type (底层类型 MyRequestData => play.api.libs.json.JsObject) 必需:_$2 个transformers.put("myRequestData", myRequestDataToJsValue)

如何解决这个问题并使用子类参数传递该函数?

【问题讨论】:

    标签: scala


    【解决方案1】:

    transformers的类型定义中缺少括号,应该是:

    val transformers: mutable.Map[String, (_ <: GeneralRequestData) => JsValue] =
        new mutable.HashMap()
    

    这告诉编译器只有函数的参数是GeneralRequestData的子类。如果没有括号,编译器期望映射值是GeneralRequestData =&gt; JsValue 的子类,但值myRequestDataToJsValue 不是这种类型的实例,因为它不接受任意GeneralRequestData

    【讨论】:

    • 值得注意的是,虽然这是 100% 正确的,并且修复了即时编译问题,但结果不会真正可用;像 transformers("myRequestData").apply(MyRequestData("Hi")) 这样的调用不会编译,因为函数的输入类型是逆变的。
    猜你喜欢
    • 1970-01-01
    • 2020-01-02
    • 2014-01-20
    • 2020-08-20
    • 1970-01-01
    • 1970-01-01
    • 2019-04-05
    • 2020-02-09
    • 2021-11-13
    相关资源
    最近更新 更多