【问题标题】:How are methods evaluated in Scala?Scala 中的方法是如何评估的?
【发布时间】:2020-09-12 03:57:59
【问题描述】:

方法类型没有价值。我们如何评估一种方法?

以SML为例,我有

fun myFunc(x) = x + 5
val b = myFunc(2)

在第二个表达式中,myFun 有一个类型和一个值,我们使用它的类型进行类型检查,并使用它的值和它的参数来评估 b 的值

但是在没有值的 Scala 方法中,我们如何评估?我对 Scala 很陌生,所以可能不太清楚。

def myFunc(x) = x + 5
val b = myFunc(2)

val b = myFunc(2)val b = 2 + 5,中间发生了什么?我们从哪里或从什么对象知道myFunc(x)x + 5

谢谢!!

【问题讨论】:

  • 您想了解方法调用在 JVM 上的工作原理吗?
  • 你能给我指点这方面的资源吗?如果一个方法不是一个值,它必须是某种东西,比如一块内存,它是什么,为什么它不能是一个值,因为它是一块内存?
  • 当我们在它上面创建一个函数值时,就像一个带有 apply() 方法的类,apply 方法指向原始方法,所以在我的理解中它必须是内存中的东西。
  • 函数本身必须是值,而不是一些神秘的定义,这对于受过命令式范式教育的传统程序员来说,过去是一个难以理解的新想法。对你来说,情况正好相反。所以我猜你的第一语言是一种功能语言,比如 SML 或 LISP。好的。认为它仅在具有动态范围的语言中很简单。对于词法,您必须具有环境和闭包,才能将函数(方法)本身作为值,所以它不是那么简单。至于 Scala,我不知道 Scala。 :)

标签: scala functional-programming substitution evaluation


【解决方案1】:

简单的答案是:仅仅因为方法不是“可以由操纵的东西”意义上的值,并不意味着它不是意义上的值的“可以由编译器的作者操作的东西”。

当然,一个方法在编译器内部会有一个代表它的对象。事实上,该对象可能看起来非常类似于表示内部函数的对象,例如 MLTon SML 编译器或 SML/NJ。

在 SML 中,语法不是一个值,但您也不会质疑如何编写函数调用,不是吗?毕竟要在SML中调用一个函数,我需要用函数调用语法来写一个函数调用,那么当语法不是一个值的时候怎么办呢?

嗯,答案是一样的:仅仅因为语法不是 程序员 可以操纵的值,编译器(或更准确地说是解析器)显然 确实了解语法。

我无法告诉你为什么决定让函数在 Scala 中成为值而不是方法,但我可以猜测一下。 Scala 是一种面向对象的语言。在面向对象的语言中,每个值都是一个对象,每个对象都有绑定到该对象的方法。所以,如果方法是对象,就需要有方法,有方法,有方法,有方法,有方法,等等。

当然,有一些方法可以解决这个问题,但它会使语言更加复杂。出于类似的原因,类不是对象(例如,在 Smalltalk、Python 和 Ruby 中不同)。请注意,即使在 Ruby 等高度反射、内省、动态的语言中,方法也不是对象。类是,但不是方法。

可以使用反射来获得一个代理对象,该对象代表一个方法,但该对象不是方法本身。实际上你也可以在 Scala 中做同样的事情。

当然也可以通过 η-expansion 将一个方法变成一个函数值。

【讨论】:

    【解决方案2】:

    我假设您正在编译为 Java 虚拟机 (JVM) 字节码,例如使用 scalac,这可能是使用 Scala 的最常见方式。免责声明:我不是 JVM 专家,所以这个答案的某些部分可能有点错误,但总体思路是正确的。

    本质上,方法是一组供运行时执行的指令。它作为磁盘上已编译代码的一部分存在(例如,.class 文件)。当 JVM 加载类时,它会将整个类文件拉入内存,包括方法。当 JVM 遇到方法调用时,它会查找该方法并开始执行其中的指令。如果方法返回一个结果,JVM 会在调用代码中使该结果可用,然后在那里做任何你想做的事情,例如分配给一个变量。

    有了这些知识,我们可以回答您的一些问题:

    从 val b = myFunc(2) 到 val b = 2 + 5,中间发生了什么?

    这不是它的工作原理,因为 JVM 并没有“扩展” myFunc,而是查找 myFunc 并执行其中的指令。

    我们从哪里或从什么对象知道 myFunc(x) 是 x + 5?

    不是来自任何物体。虽然 myFunc 位于内存中,但它位于您无法直接访问的内存区域(但 JVM 可以)。

    既然是一块内存,为什么不能是一个值?

    并非所有内存都适合类型和值的良好抽象。

    【讨论】:

      猜你喜欢
      • 2010-11-14
      • 2020-07-11
      • 1970-01-01
      • 2017-12-28
      • 1970-01-01
      • 1970-01-01
      • 2021-02-01
      • 1970-01-01
      相关资源
      最近更新 更多