【问题标题】:Function type, function value and function object in scalascala中的函数类型、函数值和函数对象
【发布时间】:2017-08-25 16:47:32
【问题描述】:

我是 scala 的新手,正在阅读 scala 中的编程。我在书中的不同页面中找到了术语函数类型、函数值和函数对象。例如:

例如,其他语言可能将对象和函数作为两个不同的概念,在 Scala 中,函数值就是对象。函数类型是可以被子类继承的类。

你能解释一下函数类型、函数值和函数对象以及它们之间的区别吗?另外上面的引用是什么意思?

【问题讨论】:

    标签: scala function


    【解决方案1】:

    让我从非函数类型、值和对象开始。

    scala> val foo:String = "bar"
    foo: String = bar
    

    这里,typeStringvaluebarobject 实例是 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) =&gt; String(取2个字符串参数和字符串类型的返回值),表达式(a:String, b:String) =&gt; a + b是编译后的function literal到一个类中,然后在运行时将其实例化为函数值。在上面的代码中,&lt;function2&gt; 是一个函数值,它本质上是一个对象。请注意,不要将函数值与从此函数调用中获得的值混淆。

    最后,foo 是一个(String, String) =&gt; String 类型的函数对象,这里函数对象和函数值也是相同的。请注意,函数值是扩展为 FunctionN 特征 的某个类的实例。这意味着:

    type: (String, String) => String = Function2[String, String]  //2 - number of parameter
    

    因此,类可以扩展为函数类型。 class A extends ((String, String) =&gt; String) 实际上被 Scala 翻译成 class A extends Function2[String, String]。此外,函数类型可以用作函数中的参数类型,这些函数是高阶函数

    【讨论】:

      【解决方案2】:

      在 Scala 中,函数与“普通”值没有什么不同。

      val inc: Int => Int = x => x + 1
      

      是同一个概念
      val s: String = "hello world"
      

      对于任何val x: T = ex 是类型为T 的值的名称,x 是评估e 的结果。

      inc 是一个值/对象,就像s 是一个值/对象一样。我认为 value 和 object 在这里本质上是一回事。

      【讨论】:

        【解决方案3】:
        val f: Int => String = i.toString
        
        • f 是一个包含对函数的引用的值,我猜它可以称为函数值。
        • Int =&gt; String是一个函数类型,对应一个从整数到字符串的函数的类型。
        • f 也是一个对象(我从未读过函数对象),例如,您可以像调用任何其他对象一样调用 f.toStringf.hashCode

        【讨论】:

          【解决方案4】:

          实际上,Scala程序员只需要知道以下三个规则就可以正确使用函数和函数值:

          • def 定义的方法和=&gt; 定义的函数字面量都是函数。它在《Scala 编程》第 4 版的第 8 章第 143 页进行了定义。
          • 函数值是可以作为任何值传递的对象。函数字面量和部分应用的函数是函数值。
          • 如果代码中的某个点需要函数值,您可以省略部分应用函数的下划线。例如:someNumber.foreach(println)

          在《Scala 编程》一书中,对象和值可以互换使用。因此,函数值和函数对象是一回事。

          【讨论】:

            猜你喜欢
            • 2020-07-30
            • 2017-09-14
            • 1970-01-01
            • 2017-02-16
            • 2016-03-10
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-04-21
            相关资源
            最近更新 更多