如何在不分配给 val 的情况下使用隐式调用返回的函数

How to call returned function with implicits without assigning to val

假设我有一个像这样的对象:

object MyObj {
  def apply(args: List[String])(implicit v: Int): Unit => Int = (_: Unit) => args.length + v
}

如果我想MyObj.apply,我必须做:

implicit val v = 5
val myObj = MyObj(List("a", "b", "c"))
myObj()

但这感觉是多余的。我希望能够做的是:

implicit val v = 5
MyObj(List("a", "b", "c"))()

不幸的是,这似乎不起作用。系统抱怨我缺少我的隐式参数,这是有道理的,但却是一个无赖。

有什么方法可以直接调用从 apply 方法返回的函数,而无需先给它赋值?

这是 scala 中的一个已知问题 2.XX 并已在 dotty 中修复。

参考这张工单的第三点:

Passing explicit arguments to implicit parameters is written like normal application. This clashes with elision of apply methods. For instance, if you have

def f(implicit x: C): A => B then f(a) would pass the argument a to the implicit parameter and one has to write f.apply(a) to apply f to a regular argument.

https://github.com/lampepfl/dotty/issues/1260

写一个

MyObj(List("a", "b", "c")).apply()

MyObj(List("a", "b", "c"))(implicitly)()

顺便说一句,接受Unit有点奇怪,通常返回Unit。也许

object MyObj {
  def apply(args: List[String])(implicit v: Int): () => Int = () => args.length + v
}

看起来更传统(我想 Int 只是为了举例,否则也不推荐像 Int 这样的标准类型的隐式)。


多蒂

object MyObj {
  def apply(args: List[String])(using v: Int): Unit => Int = (_: Unit) => args.length + v
}

given Int = 5

MyObj(List("a", "b", "c"))(()) // 8

https://scastie.scala-lang.org/tpGE0JkWT3SuQ4ri0W9dNQ