【发布时间】:2017-08-25 16:47:32
【问题描述】:
我是 scala 的新手,正在阅读 scala 中的编程。我在书中的不同页面中找到了术语函数类型、函数值和函数对象。例如:
例如,其他语言可能将对象和函数作为两个不同的概念,在 Scala 中,函数值就是对象。函数类型是可以被子类继承的类。
你能解释一下函数类型、函数值和函数对象以及它们之间的区别吗?另外上面的引用是什么意思?
【问题讨论】:
我是 scala 的新手,正在阅读 scala 中的编程。我在书中的不同页面中找到了术语函数类型、函数值和函数对象。例如:
例如,其他语言可能将对象和函数作为两个不同的概念,在 Scala 中,函数值就是对象。函数类型是可以被子类继承的类。
你能解释一下函数类型、函数值和函数对象以及它们之间的区别吗?另外上面的引用是什么意思?
【问题讨论】:
让我从非函数类型、值和对象开始。
scala> val foo:String = "bar"
foo: String = bar
这里,type 是 String,value 是 bar,object 实例是 foo。请注意,value 本质上是一个字符串类型的对象。例如,(只是为了了解值和对象之间的想法):
scala> val foo_copy = foo
foo_copy: String = bar
这里,对象foo 被分配给foo_copy。由于foo 在上述情况下是对象,因此它是对象foo_copy 的值。
现在,让我来看看函数示例:
在scala中,函数是一个值,你可以把它赋值给变量。
scala> val foo: (String, String) => String = (a:String, b:String) => a + b
foo: (String, String) => String = <function2>
这里,函数类型是(String, String) => String(取2个字符串参数和字符串类型的返回值),表达式(a:String, b:String) => a + b是编译后的function literal到一个类中,然后在运行时将其实例化为函数值。在上面的代码中,<function2> 是一个函数值,它本质上是一个对象。请注意,不要将函数值与从此函数调用中获得的值混淆。
最后,foo 是一个(String, String) => String 类型的函数对象,这里函数对象和函数值也是相同的。请注意,函数值是扩展为 FunctionN 特征 的某个类的实例。这意味着:
type: (String, String) => String = Function2[String, String] //2 - number of parameter
因此,类可以扩展为函数类型。 class A extends ((String, String) => String) 实际上被 Scala 翻译成 class A extends Function2[String, String]。此外,函数类型可以用作函数中的参数类型,这些函数是高阶函数。
【讨论】:
在 Scala 中,函数与“普通”值没有什么不同。
val inc: Int => Int = x => x + 1
和
是同一个概念val s: String = "hello world"
对于任何val x: T = e,x 是类型为T 的值的名称,x 是评估e 的结果。
inc 是一个值/对象,就像s 是一个值/对象一样。我认为 value 和 object 在这里本质上是一回事。
【讨论】:
val f: Int => String = i.toString
f 是一个包含对函数的引用的值,我猜它可以称为函数值。Int => String是一个函数类型,对应一个从整数到字符串的函数的类型。f 也是一个对象(我从未读过函数对象),例如,您可以像调用任何其他对象一样调用 f.toString 和 f.hashCode。【讨论】:
实际上,Scala程序员只需要知道以下三个规则就可以正确使用函数和函数值:
def 定义的方法和=> 定义的函数字面量都是函数。它在《Scala 编程》第 4 版的第 8 章第 143 页进行了定义。someNumber.foreach(println)
在《Scala 编程》一书中,对象和值可以互换使用。因此,函数值和函数对象是一回事。
【讨论】: