【问题标题】:How to understand function's signature of scala APIs?如何理解 scala API 的函数签名?
【发布时间】:2016-11-17 18:55:43
【问题描述】:

有时我很难理解如何调用函数。我正在研究列表并正在编写其方法的示例。

andThen 定义如下

def andThen[C](k: (A) ⇒ C): PartialFunction[Int, C]

我知道我必须将函数文字传递给andThen。所以我创建了以下有效的代码。

scala> val l = List (1,2,3,4)
l: List[Int] = List(1, 2, 3, 4)

//x:Int works
scala> val listAndThenExample = l.andThen((x:Int) => (x*2))
listAndThenExample: PartialFunction[Int,Int] = <function1>

//underscore works
scala> val listAndThenExample = l.andThen(_*2)
listAndThenExample: PartialFunction[Int,Int] = <function1>

由于列表是整数,所以 A 必须是 Int。 C 可以是任何东西,具体取决于函数字面量的输出。

上面说的有道理。

后来我尝试了applyOrElse。其签名如下

def applyOrElse[A1 <: Int, B1 >: A](x: A1, default: (A1) ⇒ B1): B1

从上面,我了解到 A1 可以是 Int 或其子类(上界),一些 B1 将是返回类型(取决于我在默认函数中所做的)。

如果我对 A1 和 B1 的理解是正确的,那么 x 将是 Int 或其子类,并且默认函数字面量应该采用 Int(或子类)并返回一些 B1。我尝试如下调用该函数,但当我使用y:Int 时它不起作用,但在我使用_:Int 时它起作用。我不明白为什么。

scala> val l = List (1,2,3,4)
l: List[Int] = List(1, 2, 3, 4)

//this doesn't work
cala> val listApplyOrElse = l.applyOrElse(y:Int,(x:Int)=>println("Wrong arg "+x))
<console>:12: error: not found: value y
       val listApplyOrElse = l.applyOrElse(y:Int,(x:Int)=>println("Wrong arg "+x))
                                           ^
//but underscor works
scala> val listApplyOrElse = l.applyOrElse(_:Int,(x:Int)=>println("Wrong arg "+x))
listApplyOrElse: Int => AnyVal = <function1>

问题 - 为什么 x:Int 和 _:Int 都适用于 andThen 而不适用于 applyOrElse?

问题 - 什么是“A”,为什么 B1 与 A 相关?

【问题讨论】:

  • l.applyOrElse(_:Int,(x:Int)=&gt;println("Wrong arg "+x)) 转换为 (y: Int) =&gt; l.applyOrElse(y, (x:Int)=&gt;println("Wrong arg "+x))

标签: scala


【解决方案1】:

根据文档,applyOrElse(x, default) 相当于

if (pf isDefinedAt x) pf(x) else default(x)

在这种情况下,您的部分函数是一个列表,即从索引 (0 到 3) 到值 (1,2,3,4) 的函数。所以当你这样做时

l.applyOrElse(y,(x:Int)=>println("Wrong arg "+x))

您的意思是“如果有意义,请致电 l(y),否则请致电 println("Wrong arg"+y)”。编译器合理地回应,“y 是什么?”

如果您使用实际值,它会按预期工作

l.applyOrElse(3 ,(x:Int)=>println("Wrong arg "+x)) // returns 4
l.applyOrElse(8 ,(x:Int)=>println("Wrong arg "+x)) // prints Wrong arg 8

使用下划线做一些完全不同的事情,你会得到一个部分应用函数(这与部分函数完全不同!)

val f = l.applyOrElse(_:Int, (x:Int)=>println("Wrong arg "+x))
f(8) // prints Wrong arg 8

【讨论】:

    【解决方案2】:

    你还没有声明 y,所以尝试使用它是一个错误。 _:Int 有效,因为它现在正在创建一个部分应用的函数。注意返回类型不是一个值,而是一个函数。这个返回的函数是 applyOrElse 已经提供了第二个参数(但不是第一个)。

    在您的andThen 示例中,_ 的使用意味着不同,特别是它是函数文字的简写符号。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-09-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-20
      相关资源
      最近更新 更多