提升方法运行时出错

Error in lifting method to function

我有一个带有隐式参数的方法。在 2 种情况下将其转换为函数时出现错误:

1:

def action(implicit i:Int) =  i + " in action"
val f = action _

然后我收到 WhosebugError。

2:

def action(implicit i:Int) =  i + " in action"
val f = action(_)

然后我得到一个错误:缺少参数类型

我必须这样写:

val f = (i:Int) => action(i)

没关系。如果 'action' 的参数不是 implicit ,则所有情况都是正确的。那么如何解释,我想念什么?

如果您将函数的参数指定为 implicit,您是在邀请编译器为您提供该参数的值。那么编译器如何找到这些值呢?它查找在各种 范围 .

中已声明为 implicit 值的相同类型的值(在您的情况下为 Int

(为简单起见,我将在此示例中仅使用局部作用域,但您可能需要阅读有关此主题的内容。Programming in Scala, 3rd Ed 是很好的第一步。)

请注意,implicit 值的名称将被忽略并且与程序无关,编译器仅查看 implicit 值的类型。如果在同一作用域中找到具有所需类型的多个 implicit 值,则编译器将抱怨 不明确的隐式值 .

例如,下面提供了一个带有隐式参数和当前范围内该参数默认值的函数:

def greetPerson(name: String)(implicit greeting: String) = s"$greeting $name!"
implicit val defaultGreeting = "Hello" // Implicit value to be used for greeting argument.
val y = greetPerson("Bob") // Equivalent to greetPerson("Bob")(defaultGreeting).
val z = greetPerson("Fred")("Hi")

注意y只是"Hello Bob!"的一个String值,而z是一个字符串,其值为"Hi Fred!";它们都不是函数。

另请注意 greetPerson 是一个 curried 函数。这是因为 implicit 参数不能与同一参数列表中的常规非 implicit 参数混合。

通常,使用常见类型(IntBooleanString 等)作为 implicit 参数的值是一种不好的做法。在一个大程序中,您的作用域中可能有很多不同的 implicit 值,您可能会选择一个意想不到的值。出于这个原因,标准做法是将这些值包装在 案例 class 中。

如果您尝试创建一个值来提供另一个函数(即 部分应用的函数)的一些参数,那么它看起来像这样:

def greetPerson(greeting: String, name: String) = s"$greeting $name!"
val sayHello = greetPerson("Hello", _: String)
val y = sayHello("Bob") // "Hello Bob!"
val sayHi = greetPerson("Hi", _: String)
val z = sayHi("Fred") // "Hi Fred!"

在这两种情况下,我们都在创建 部分应用函数sayHisayHello)调用 greetPersongreeting 参数指定,但允许我们指定 name 参数。 sayHellosayHi 仍然只是值,但它们的值是 部分应用函数 而不是常量。

根据您的情况,我认为后一种情况可能更适合您...

我还会阅读下划线字符 (_) 在 Scala 中的使用方式。在部分应用的函数声明中,它对应于稍后将提供的参数。但它还有很多其他用途。我认为除了阅读 Scala 并学习如何以及何时使用它们之外别无选择。