Scala中的右箭头意义

Saw*_*yer 20 scala

在Scala编程的第9章中,有一个这样的示例方法:

def twice(op: Double => Double, x: Double) = op(op(x))
Run Code Online (Sandbox Code Playgroud)

作者在书中说:

此示例中的op类型为Double => Double,这意味着它是一个函数,它将一个Double作为参数并返回另一个Double.

我不明白这里的"Double => Doulbe"是什么,在前面的章节中,"=>"只表示函数文字,而且从未写过这样的"Type => Type",因为根据scala函数文字语法定义函数体的右边部分是函数体,函数体怎么能"双"?

Bri*_*Hsu 45

因为它有两个用法.

首先,您可以使用=>来定义函数文字.

scala> val fun = (x: Double) => x * 2
fun: (Double) => Double = <function1>

scala> fun (2.5)
res0: Double = 5.0
Run Code Online (Sandbox Code Playgroud)

这很容易.但这里的问题是,什么类型fun?它是一个"将Double作为参数并返回双精度的函数",对吧?

那么我怎么能用它的类型注释乐趣呢?那是(Double) => (Double).那么,前面的例子可以改写为:

scala> val fun: Double => Double = (x: Double) => x * 2
fun: (Double) => Double = <function1>

scala> fun (2.5)                                       
res1: Double = 5.0
Run Code Online (Sandbox Code Playgroud)

好的,那么下面的代码是做什么的?

def twice(op: Double => Double, x: Double) = op(op(x))
Run Code Online (Sandbox Code Playgroud)

好吧,它告诉你op是a (Double => Double),这意味着它需要一个带Double的函数并返回一个Double.

所以你可以将前一个fun函数传递给它的第一个参数.

scala> def twice(op: Double => Double, x: Double) = op(op(x))    
twice: (op: (Double) => Double,x: Double)Double

scala> twice (fun, 10)
res2: Double = 40.0
Run Code Online (Sandbox Code Playgroud)

这将是等同于更换opfun,并更换x10,那就是fun(fun(10)),其结果将是40.


Aar*_*rup 12

除了在函数文本中将参数列表与函数体分离之外,双箭头还可以用作FunctionN类型的语法糖:

T => R 手段 Function1[T, R]

(T1, T2) => R 手段 Function2[T1, T2, R]

...

在您的示例中,这意味着该op函数采用Double并返回Double(如作者所解释的).

另一个例子,它可以写

// declare len as a function that takes a String and returns an Int,
// and define it as returning the length of its argument
val len: String => Int = { _.length }

// or, a more verbose version that uses '=>' in both ways
val len: String => Int = { (s: String) => s.length }

len("apple") // returns 5
Run Code Online (Sandbox Code Playgroud)