【问题标题】:Scala: issues using functions as first class objectsScala:使用函数作为第一类对象的问题
【发布时间】:2010-07-31 16:20:41
【问题描述】:

我需要一个通用函数的集合,但我无法以我喜欢的方式完成它。 我创建了一个

List[(Any)=>Unit]

但是一旦我尝试插入一个函数,例如一个

String=>Unit

我得到一个错误。如何声明一个不考虑参数和返回值类型的泛型函数集合?

【问题讨论】:

    标签: scala function contravariance


    【解决方案1】:

    函数在输入类型参数中是逆变的,例如在你的情况下Function1[-T1,+R]。这意味着您可以将Any => Unit 的实例添加到List[String => Unit],但反之则不行。这当然是有道理的,因为您不能使用 Any 类型的参数调用期望类型为 String 的参数的函数。

    【讨论】:

      【解决方案2】:

      为了完成@Moritz 的回答,您需要为T1 选择类型参数,它是列表中每个函数的输入类型的子类型。 Nothing 符合要求——它是每种类型的子类型。

      scala> val l: List[Nothing => Any] = List((b: String) => b, (a: Int) => a)
      l: List[(Nothing) => Any] = List(<function1>, <function1>)
      

      存在类型也可以:

      scala> val l: List[_ => _] = List((b: String) => b, (a: Int) => a)        
      l: List[Function1[_, _]] = List(<function1>, <function1>)
      

      【讨论】:

      • 如何调用签名为(Nothing)=&gt;Any的函数?
      • 你不能,没有演员表。但是这个问题并没有要求:)
      • 有没有办法动态(可能通过反射)获取函数的实际类型,以便我可以执行转换?
      • 在运行时,它的类型参数被擦除,它只是一个def apply(v: AnyRef): AnyRef
      猜你喜欢
      • 1970-01-01
      • 2017-02-16
      • 1970-01-01
      • 1970-01-01
      • 2016-12-05
      • 2020-07-11
      • 2019-07-23
      • 2016-04-19
      • 2022-01-27
      相关资源
      最近更新 更多