首先,这更多是为了实验和学习,我知道我可以直接传递参数。
def eval(xs: List[Int], message: => String) = {
xs.foreach{x=>
implicit val z = x
println(message)
}
}
def test()(implicit x : Int) = {
if(x == 1) "1" else "2"
}
eval(List(1, 2), test)//error: could not find implicit value for parameter x
这是否可能,我只是没有正确使用implicits的情况?或者根本不可能?
答案 0 :(得分:3)
隐式参数在编译时解析。 By-name参数捕获它在传入的范围内访问的值。
在运行时,没有任何隐含的概念。
eval(List(1, 2), test)
这需要在编译时完全解决。 Scala编译器必须弄清楚调用test
所需的所有参数。它会尝试在范围内找到隐含的Int
变量,其中eval
被称为。在您的情况下,eval
中定义的隐式值在运行时不会产生任何影响。
答案 1 :(得分:1)
如何获取隐式值始终在编译时解决。没有具有隐式参数的Function
对象。要从具有隐式参数的方法获取可调用对象,您需要使它们显式化。如果你真的想要,你可以将其包装在另一个使用含义的方法中:
def eval(xs: List[Int], message: Int => String) = {
def msg(implicit x: Int) = message(x)
xs.foreach { x =>
implicit val z = x
println(msg)
}
}
eval(List(1, 2), test()(_))
这样做你可能无法获得任何收益。
Implicits不是传递参数的替代方法。它们是显式输入您传入的参数的替代方法。然而,实际传入的方式相同。
答案 2 :(得分:0)
我假设您希望隐式参数x
(在test
的签名中)由隐式变量z
填充(在eval
中)。
在这种情况下,z
超出了x
可以看到z
的范围。隐式解析由编译器静态完成,因此运行时数据流不会影响它。要详细了解范围,this answer中的Where do Implicits Come From?
会有所帮助。
但是你仍然可以像这样使用implicit
。 (我认为这是对implicit
的误用,所以仅用于演示。)
var z = 0
implicit def zz: Int = z
def eval(xs: List[Int], message: => String) = {
xs.foreach{ x =>
z = x
println(message)
}
}
def test()(implicit x : Int) = {
if(x == 1) "1" else "2"
}
eval(List(1, 2), test)