如何在运行时使用隐式?
How to use an implicit at runtime?
首先,这更多的是为了实验和学习,我知道我可以直接传递参数。
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
这甚至可能吗,我只是没有针对这种情况正确使用隐式?或者根本不可能?
我假设您希望隐式参数 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)
隐式参数在编译时解析。按名称参数捕获它在传入范围内访问的值。
在运行时,没有任何隐含的概念。
eval(List(1, 2), test)
这需要在编译时完全解决。 Scala 编译器必须计算出调用 test
所需的所有参数。它将尝试在调用 eval
的 范围内找出隐式 Int
变量 。在您的情况下,eval
中定义的隐式值在运行时不会产生任何影响。
如何获取隐式值始终在编译时解决。没有带有隐式参数的 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()(_))
这样做你可能不会有任何收获。
隐式不能替代传递参数。它们是显式输入您传递的参数的替代方法。但是,实际传递的方式相同。
首先,这更多的是为了实验和学习,我知道我可以直接传递参数。
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
这甚至可能吗,我只是没有针对这种情况正确使用隐式?或者根本不可能?
我假设您希望隐式参数 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)
隐式参数在编译时解析。按名称参数捕获它在传入范围内访问的值。
在运行时,没有任何隐含的概念。
eval(List(1, 2), test)
这需要在编译时完全解决。 Scala 编译器必须计算出调用 test
所需的所有参数。它将尝试在调用 eval
的 范围内找出隐式 Int
变量 。在您的情况下,eval
中定义的隐式值在运行时不会产生任何影响。
如何获取隐式值始终在编译时解决。没有带有隐式参数的 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()(_))
这样做你可能不会有任何收获。
隐式不能替代传递参数。它们是显式输入您传递的参数的替代方法。但是,实际传递的方式相同。