我的假设是,如果系统中某处有一个标记为隐式的值:
implicit val moo = "World!"
然后它可以随时随地“从空中摘取”?
这是正确的吗?
所以如果我现在有以下代码:
import Execution.Implicits._
def myFunc(stub:String)(implicit imp:String) = {
//the compiler now knows that imp should be the same as moo
println(stub + " " + imp)
}
myFunc("Hello") // <- should print "Hello World!"
但是,我怎样才能避免将函数的签名实际定义为采用隐式?这意味着在调用链的所有路径上,我都必须将它包含在参数中,这不符合隐式的预期用途。我怎样才能真正地“从空中摘取它”?
谢谢
最佳答案
简而言之,你不能。
以下是您的选择:
转发隐式
假设您有一个执行 Future
的函数并且您需要一个 ExecutionContext
:
您可以在与 someFun
相同的文件中 import scala.concurrent.ExecutionContext.Implicits.global
(或定义您自己的等),然后您会得到:
import scala.concurrent.ExecutionContext.Implicits.global
def someFun(): Future[SomeThing] = {
Future(something)
}
或者,如果您不想在与 someFun
相同的文件(类、对象等)中导入,则转发隐式。这样,当您在另一个文件中使用 someFun
时,您可以导入它。
def someFun()(implicit ex: ExecutionContext): Future[SomeThing] {
Future(someThing)
}
上下文边界
听起来这就是你想要的,只是你没有正确实现它。
class Stub[T](name: String)
def myFunc[T: Moo](stub: Stub[T]) = {
println(stub + " " + implicitly[Moo[String]])
}
以上相当于:
def myFunc[T](stub: T)(implicit evidence: Moo[T]) = {
println(stub + " " + evidence.toString)
}
查看边界
或者,如果将 Stub
隐式转换为 Moo
而不是绑定(bind)它更有意义:
def myFunc[T <% Moo](stub: T) = {
println(stub + " " + implicitly[Moo[T]])
}
要使用上面的内容,您需要提供具体化的隐式(例如,一种将 stub 转换为 Moo 的方法)。例如:
implicit def stubToMoo[T](stub: Stub[T]): Moo[T] = {
new Moo(stub) // or whatever
}
最重要的是,在您的问题中,隐式的使用毫无意义。您可以按照您的描述进行“稀薄”导入,但根据上述选项,看看是否值得。
关于scala - 如何在不将其传递给函数的情况下使用隐式值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22608656/