【问题标题】:Scala Function1 Generic parameter and return typeScala Function1 泛型参数和返回类型
【发布时间】:2016-08-15 05:52:53
【问题描述】:

假设我想存储一个Map[String, Function1],其中 Function1 的参数和返回类型可以变化。我将如何将Function1[String, String]Function1[Int, Int] 存储在同一个地图中。

我尝试过Function1[AnyRef, AnyRef],但Function1[String, String] 不是Function1[AnyRef, AnyRef],因此无法编译。

【问题讨论】:

  • 我认为你不能以类型安全的方式做到这一点
  • 你能存储一个ADT,即sealed trait MyFn | case class Fn1(f: Int => Int) extends MyFn | case class Fn2(f: String => String)吗?然后,对Map#get 结果进行模式匹配,即Option[MyFn]
  • 要编译的类型是Nothing => Any,它可以接受任何函数。见val f: Nothing => Any = (a: String) => a.toInt

标签: scala function types


【解决方案1】:

如果你只有两种可能的值类型,你可以将值包装在Either

val m = Map[String, Either[Int => Int, String => String]]()

如果您想存储两种以上的不同类型,请创建自己的包装器,或使用Coproduct from shapeless 之类的东西。

【讨论】:

    【解决方案2】:

    这看起来像你所追求的吗?

    scala> val m = Map[String, Function1[_,_]]()
    m: scala.collection.immutable.Map[String,Function1[_, _]] = Map()
    
    scala> val f1 = (i:Int) => i*3
    f1: Int => Int = <function1>
    
    scala> val f2 = (b: Boolean) => if (b) "YES" else "NO"
    f2: Boolean => String = <function1>
    
    scala> m + ("xcx" -> f2) + ("rtr" -> f1)
    res59: scala.collection.immutable.Map[String,Function1[_, _]] = Map(xcx -> <function1>, rtr -> <function1>)
    

    【讨论】:

    • 我不认为你可以在从地图中检索到这些功能后真正使用它们
    • 检索到的函数是可用的,但你必须强制转换它,m("rtr").asInstanceOf[Function1[Int,Int]](4),这很好地表明你需要重新考虑这种方法。
    • 这样做的目的是为类的字段保存一堆转换函数。因此,给定一个 POJO 列表(或 Scala 等效类),获取对象类的字段(例如 val someString、val someInt 等)并应用可以返回任何其他类型的给定函数(例如将 someString 转换为 aLong ) 通过使用反射的所述字段的名称,用于 POJO 列表中的每个项目。
    猜你喜欢
    • 1970-01-01
    • 2016-11-13
    • 1970-01-01
    • 2016-09-16
    • 2021-05-01
    • 1970-01-01
    • 2018-02-23
    • 1970-01-01
    • 2013-01-26
    相关资源
    最近更新 更多