【问题标题】:What are the definitions of named method and named function?命名方法和命名函数的定义是什么?
【发布时间】:2011-11-12 16:54:55
【问题描述】:

我已经阅读了Difference between method and function in Scala 的问题以及许多关于方法和函数之间差异的文章。我有一种感觉,“方法”只是一个“命名函数”,定义为类、特征或对象中的方法。 “函数”代表那些文章中的“匿名函数”或“函数文字”或“函数对象”之类的东西。可以在《Scala 编程http://www.artima.com/shop/programming_in_scala_2ed》一书中找到证据,第 141 页,第 8.1 节,“定义函数的最常见方法是作为某个对象的成员。这样的函数称为方法。”

但是,当我查看 Scala 语言参考http://www.scala-lang.org/docu/files/ScalaReference.pdf 时,有一些概念,比如命名方法。在第 91 页,第 6.20 节返回表达式:“返回表达式 return e 必须出现在一些封闭命名的主体内 方法或函数。”您还可以在同一页面和其他地方找到术语“命名函数”。

所以我的问题是,在 Scala 中,方法、命名方法和命名函数是指同一个概念吗?你从哪里得到命名函数的定义?

在代码List(1, 2).map(_ + 1)中,原来的表达式_ + 1是一个命名方法,然后将方法转换成一个函数。什么样的函数,匿名函数,函数对象,命名函数?

在我的理解中,Scala 只有两种类型的函数:命名函数是方法;一个匿名函数,它是一个函数字面量。函数字面量被编译成 trait FunctionN 的函数对象,以便在 Scala 的纯面向对象世界中使用。

但是,对于上述代码中的_ + 1 等常规命名函数/方法,为什么Scala 会将其转换为另一个函数对象?

【问题讨论】:

    标签: function scala methods anonymous named


    【解决方案1】:

    链接问题的答案很好地涵盖了这一点,但要解决您的具体问题:

    • method => 你用def关键字定义的东西
    • 命名方法 => 相同,所有方法都有名字
    • 命名函数 => 已分配给值或从方法转换的函数。与匿名函数相比。

    方法和函数之间的区别有点像Java 中int 原语和装箱Integer 之间的区别。

    在一般讨论中,通常将两者都描述为“整数”。这通常不是问题,但您必须注意在区别 相关的地方保持精确。

    同样,当您的程序需要方法时,它会自动转换为函数(因此也是对象),就像装箱原语一样。因此,将方法称为函数并完全错误。

    更新

    那么它是如何工作的呢?

    当您尝试将方法作为参数传递给例如List[A].map,编译器将生成一个派生Function1[A,B] 的内部类(具有合成名称),以及一个委托给您最初提供的方法的apply 方法。然后这个实例将作为实际参数传递。

    【讨论】:

    • 拳击比较有帮助。我知道 Scala 需要将函数文字转换为 FunciontN 的方法,因为 Scala 是一种面向对象的语言。但是,如果您提供映射常规对象方法,为什么 Scala 会将一个方法“装箱”到另一个方法中呢?
    • 一个方法永远不会被“装箱”成另一个方法,只能装成一个函数。当您将方法指定为例如的参数时List[A].map,它实际上是作为函数 A => B 传递的。在内部,map 方法将在提供的函数实例上调用 apply,而该实例又将调用您指定的方法。
    【解决方案2】:

    在语言层面,只有两个概念,

    • 方法 是 Scala 的基本构建块。方法总是被命名。方法存在于类或特征中。方法是 JVM 原生的构造,因此在 Scala 和 Java 中是相同的。 Scala 中的方法(与函数不同)可能具有特殊功能:它们可以通过类型参数进行抽象,它们的参数可以具有默认值或隐式等。

    • 函数对象只是函数特征的实例(Function1Function2,...)。当函数对象上的apply 方法被调用时,函数被评估。定义未命名的“匿名”函数(又名“函数文字”)有特殊语法。函数只是一个值,因此可以命名(例如,val f: (Int => Int) = (x => x))。 A => B 类型是 Function1[A, B] 的简写。

    linked SO question 中提到,一些参考文献(如 Scala 规范)不准确地使用“函数”一词来表示“方法”或“函数对象”。我猜部分原因是方法可以根据上下文自动转换为函数对象。但是请注意,相反的转换是没有意义的:方法不是存在于堆上且独立存在的一流值。相反,方法与定义它的类有着千丝万缕的联系。

    【讨论】:

    • 函数->方法转换是不可避免的,所讨论的方法是函数类中定义的apply。非常像我的原始拳击类比 :)
    • 我会换一种说法:每个函数代表在函数类的实例上定义的apply 方法。这里没有转换,这就是函数的定义方式。另一方面,将方法转换为函数实际上确实会分配和构建新的东西。
    • 我问这个问题是因为方法和函数术语的混合让我感到困惑——方法是函数吗?还是命名函数?还是根本不是功能?这个答案使用了最后一个定义,即方法不是函数。从 Scala 语言规范来看,这个定义是不正确的(见我上面的问题)。这是我试图澄清的事情。
    • 你是对的:“函数”在非技术意义上被用作方法以及函数对象的通用术语。更新了答案以澄清这一点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-15
    • 1970-01-01
    • 2012-11-21
    • 1970-01-01
    相关资源
    最近更新 更多