带隐式参数的apply函数需要显式参数

时间:2014-09-04 03:19:48

标签: scala implicit

我无法弄清楚为什么这不起作用:

case class Expression extends Node[Doube] {

   def apply(implicit symbolTable: Map[String,Double]) = value
}

请注意,值在Node中定义,也带有隐式符号表参数。

当我尝试这样调用它时:

implicit val symbolTable = Map("a"->1, "b"->2)
//and x is an Expression, then:

x() // does not compile (can't find implicit) but 
x(symbolTable) // works fine

奇怪的是:

x.value // works fine too

如果我这样写申请:

def apply()(implicit symbolTable: Map[String,Double]) 

它有效,但我不明白为什么我需要这样做....

任何指针?

1 个答案:

答案 0 :(得分:1)

spec区分了价值转化与方法转化。

x是一个值。对于具有两个参数列表的示例,x()是一个具有一个参数列表的方法类型,隐式一个,隐式提供。

对于您的原始示例,使用一个隐式参数列表,x()无法提供所需的参数。 (不是"隐含未找到。")

scala> def f(implicit s: String) = 42
f: (implicit s: String)Int

scala> f
<console>:9: error: could not find implicit value for parameter s: String
              f
              ^

scala> f()
<console>:9: error: not enough arguments for method f: (implicit s: String)Int.
Unspecified value parameter s.
              f()
               ^

对于要提供的implicits,您不得提供参数列表。

对于您的奇怪x.value,显然value是一个带有一个隐式参数列表的方法。

更多:

scala> object x { def apply(implicit s: String) = 42 }
defined object x

scala> x.apply
<console>:9: error: could not find implicit value for parameter s: String
              x.apply
                ^

scala> implicit val s: String = "hi"
s: String = hi

scala> x.apply
res1: Int = 42

scala> x()
<console>:10: error: not enough arguments for method apply: (implicit s: String)Int in object x.
Unspecified value parameter s.
              x()
               ^

当您按上述方式编写x.apply时,它将提供parens将其转换为应用程序,提供隐式args,或者尝试将其转换为函数(如果上下文需要)。