【问题标题】:Scala Argument Types of Anonymous Function in Overload重载中匿名函数的Scala参数类型
【发布时间】:2017-02-01 20:35:54
【问题描述】:

关于 SO 上的此错误消息有很多问题,但似乎都与此问题无关。

The argument types of an anonymous function must be fully known. (SLS 8.5)

有问题的代码块试图模拟 Ruby 的块功能,另外还有一个好处是参数可以在过程中进行模式匹配。

object Block {
  def apply(f: => Unit) = apply((_: String) => f)
  def apply(f: String => Unit) = ???
}
def example() = {
  Block { // Error!
    case "A" => println("First letter of the alphabet")
    case _   => println("Not the first letter of the alphabet")
  }
}

即使向下一行,Scala 可以清楚地看到我正在匹配一个字符串,但它无法推断参数类型。

【问题讨论】:

    标签: scala anonymous-function overloading


    【解决方案1】:

    这里的麻烦是有两个apply 方法。如果只有一个:

    object Block {
      def apply(f: String => Bool) = ???
    }
    

    然后一切都会正常工作,因为 Scala 会看到应用程序并立即了解所需的匿名函数类型。但是,当有两种或多种不同的方法时:

    object Block {
      def apply(f: => Bool) = apply((_: String) => f)
      def apply(f: String => Bool) = ???
    }
    

    Scala 无法从apply 的应用中推断出参数的类型,也无法从参数的类型中推断出apply 的哪个应用,因此陷入了循环。似乎最简单的解决方案是简单地重命名其中一个方法。

    object Block {
      def apply(f: => Unit) = apply((_: String) => f)
      def branchOff(f: String => Unit) = ???
    }
    

    现在打电话也不是难事了。

    Block { println("This is a regular application.") }
    Block.branchOff {
      case "A" => println("A is for aardvark")
      case "B" => println("B is for beaver")
      case _   => println("Huh?")
    }
    

    您不必为此指定任何类型参数或任何显式参数。

    更多详情请参见 GitHub 上的一个帖子:https://github.com/ReactiveX/RxScala/issues/160

    【讨论】:

      【解决方案2】:

      如果您真的喜欢拥有两种不同的apply() 方法的想法,那么您必须为推理引擎提供一些帮助。

      def example() = {
        Block{s:String => s match {
          case "A" => println("First letter of the alphabet")
          case _   => println("Not the first letter of the alphabet")
        }}
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-05-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-05-22
        • 1970-01-01
        • 1970-01-01
        • 2011-02-21
        相关资源
        最近更新 更多