scala - 如何在不将其传递给函数的情况下使用隐式值?

标签 scala

我的假设是,如果系统中某处有一个标记为隐式的值:

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/

相关文章:

scala - 组合子类型化(在 Scala 中)

scala - Jrebel/SBT如何在不重启的情况下重新编译webapp

java - Scala 阻塞图

scala - 在需要 Concurrent 和 Timer 类型类实例的测试中使用什么类型?

java - 可以使用 Java 中的 GraphX 将 CSV 文件转换为图形吗

scala - 在 ScalaCheck 中生成任意 Function1

VIM 和 Scala -- 缩进问题?

scala play twitter api oauth 身份验证不起作用

scala - 如何基于字符对字符串进行模式匹配?

scala - 玩!斯卡拉 : How to disable actor modules loaded at the start of the application when testing?