Scala:对具有隐式、柯里化(Currying)和默认值的重载方法的偏好

标签 scala

下面的简单代码无法编译:

object O { 
  def apply(s:String, o:Int=5)(implicit i:String) = { 
    println("am first"); 
    s 
  }

  def apply(s:String)(o:Boolean*) = { 
    println("am second"); 
    o 
  } 
}

object Main extends App {
  implicit val myS = "foo"
  O("test")
}

错误是

error: missing arguments for method apply in object O;
follow this method with `_' if you want to treat it as a partially applied function
  O("test")
   ^
one error found

这似乎是因为编译器更喜欢第二个apply。但这是为什么呢?特别是考虑到申请第一个apply的条件满足了?如果我删除第二个apply,那么这段代码可以正常编译。

有什么方法可以“引导”编译器正确编译它吗?或者我被迫创建两个不同的方法名称?

最佳答案

你说得对,Scala 编译器有可能变得更智能。问题是没有人愿意为此提出新的规范。这会非常复杂。

有一些方法可以绕过此限制。

1。将重载替换为 apply 中的模式匹配,以选择两个函数之一

def apply(s: String, i: Option[Int] = None) = {
  i match {
    case Some(n) => // call the 1st
    case None => // call the 2nd
 }

}

然后:

apply("test", Some(5)) => ... // if we want the first
apply("test") => ... // if we want the second

2。使用重载,但两个函数使用不同的参数名称:

def apply(apple: String, o: Int = 5)(implicit i: String)
def apply(banana: String)(o: Boolean*) 

然后:

apply(apple = "test") // if we want the first    
apply(banana = "test") // if we want the second

关于Scala:对具有隐式、柯里化(Currying)和默认值的重载方法的偏好,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31316590/

相关文章:

scala - 向 Spark 提交任务

java - IntelliJ Idea - 在 Mac 上安装 JDK 1.8

scala - 是否可以将命名参数用于 Scala 案例类匹配?

scala - 为什么我的 akka 日志在游戏中不起作用

list - Scala 中 Seq 和 List 的区别

scala - 从上到下打印供应商段

java - 从 Java 实例化一个 Scala 类,并使用构造函数的默认参数

scala - 需要层次结构时如何使用案例类?

scala - 如何修复错误 : "org.jetbrains.jps.incremental.scala.remote.ServerException java.lang.StackOverflowError"

java - 更新两个并发的 hashmaps 保持自动性