为了账号安全,请及时绑定邮箱和手机立即绑定

Scala中方法和函数的区别

Scala中方法和函数的区别

Scala中方法和函数的区别我读Scala函数(部分)又一次斯卡拉之旅)。在该职位上,他说:方法和函数不是一回事。但他没有解释这件事。他想说什么?
查看完整描述

3 回答

?
呼啦一阵风

TA贡献1802条经验 获得超6个赞

首先,让我们看看Scala规范告诉我们什么。第三章(类型)告诉我们功能类型(3.2.9)和方法类型(3.3.1)。第四章(基本宣言)谈到价值宣言和定义 (4.1), 可变声明和定义(4.2)和函数声明和定义(4.6)。第六章(词组)谈到匿名函数(6.23)和方法值(6.7)。奇怪的是,函数值只在3.2.9上提到过一次,而在其他地方则没有。

功能类型(大致上)是表单的一种类型。(T1,.,TN)=>U,这是特征的缩写。FunctionN在标准图书馆里。匿名函数方法值有函数类型,函数类型可以用作值、变量和函数声明和定义的一部分。实际上,它可以是方法类型的一部分。

方法类型非值型..这意味着值-没有对象,没有实例-具有方法类型。如上文所述,a方法值实际上有一个功能类型..方法类型是def声明-关于def除了它的身体。

价值声明和定义变量声明和定义valvar声明,包括两者类型和价值-分别可以是,功能类型匿名函数或方法值..注意,在JVM上,这些(方法值)是用Java所称的“方法”实现的。

功能声明def声明,包括类型体体..类型部分是方法类型,而主体是表达式或块..这也是用Java所谓的“方法”在JVM上实现的。

最后,匿名函数功能类型(特征的一个例子)FunctionN),以及方法值都是一样的!区别在于方法值是通过后置下划线(m _是对应于“函数声明”的方法值(defm),或者通过一个名为ETA-扩张,这就像一种从方法到功能的自动转换。

规格是这么说的,所以让我把这个放在最前面:我们不使用这个术语!这会导致所谓的混乱“功能声明”,这是程序的一部分(第4章-基本声明)和“匿名函数”,这是一个表达式,并且“功能类型”这是一种类型-一种特质。

以下术语和经验丰富的Scala程序员使用的术语与规范的术语有一处不同:而不是说功能声明,我们说方法..甚至方法声明。此外,我们注意到价值声明变量声明也是实用的方法。

因此,考虑到上述术语的变化,下面是对这一区别的实用解释。

功能是一个对象,该对象包括FunctionX特征,如Function0Function1Function2等可能包括PartialFunction也是,这实际上扩展了Function1.

让我们看看其中一个特征的类型签名:

trait Function2[-T1, -T2, +R] extends AnyRef

这个特性有一个抽象的方法(它也有一些具体的方法):

def apply(v1: T1, v2: T2): R

这告诉了我们所有需要知道的事情。一个功能有一个apply接收N类型参数t1T2, ..., 总氮,并返回某种类型的东西。R..它对它所接收的参数是对变的,在结果上是协变的.

这个差异意味着Function1[Seq[T], String]Function1[List[T], AnyRef]..作为一个子类型意味着它可以被使用。代替它。如果我要打电话f(List(1, 2, 3))并期望AnyRef以上两种类型中的任何一种都可以工作。

现在,什么是相似性一种方法和一种功能?好吧,如果f是一个函数m是一个局部变量的方法,那么这两个方法都可以这样调用:

val o1 = f(List(1, 2, 3))val o2 = m(List(1, 2, 3))

这些调用实际上是不同的,因为第一个调用只是一个语法糖。Scala将其扩展为:

val o1 = f.apply(List(1, 2, 3))

当然,它是对象的方法调用。f..函数还具有其他语法糖的优势:函数文字(实际上是其中的两个)和(T1, T2) => R输入签名。例如:

val f = (l: List[Int]) => l mkString ""val g: (AnyVal) => String = {
  case i: Int => "Int"
  case d: Double => "Double"
  case o => "Other"}

方法和函数之间的另一个相似之处是,前者可以很容易地转换为后者:

val f = m _

Scala将扩展那,那个,假设m类型是(List[Int])AnyRef转入(Scala 2.7):

val f = new AnyRef with Function1[List[Int], AnyRef] {
  def apply(x$1: List[Int]) = this.m(x$1)}

在Scala2.8上,它实际上使用了AbstractFunction1类以减少班级大小。

注意,一个函数不能反过来转换-从一个函数转换到一个方法。

然而,方法有一个很大的优势(嗯,两个-它们可以稍微快一点):它们可以接收。类型参数..例如,同时f上面可以指定List它收到(List[Int](在示例中),m可以参数化它:

def m[T](l: List[T]): String = l mkString ""

我认为这几乎涵盖了一切,但我很乐意用任何问题的答案来补充这一点。


查看完整回答
反对 回复 2019-06-05
?
湖上湖

TA贡献2003条经验 获得超2个赞

方法和函数之间的一个很大的实际区别是return手段。return只有从方法中返回。例如:

scala> val f = () => { return "test" }<console>:4: error: return outside method definition       val f = () => { return "test" }
                       ^

从方法中定义的函数返回非本地返回:

scala> def f: String = {                 
     |    val g = () => { return "test" }
     | g()                               
     | "not this"
     | }f: Stringscala> f
res4: String = test

而从本地方法返回只能从该方法返回。

scala> def f2: String = {         
     | def g(): String = { return "test" }
     | g()
     | "is this"
     | }f2: Stringscala> f2
res5: String = is this


查看完整回答
反对 回复 2019-06-05
?
鸿蒙传说

TA贡献1865条经验 获得超7个赞

功能可以使用参数列表调用函数以生成结果。函数具有参数列表、主体和结果类型。作为类、特征或单例对象的成员的函数被调用。方法..在其他函数中定义的函数称为局部函数。带有结果类型Unit的函数称为过程。源代码中的匿名函数称为函数文本。在运行时,函数文本被实例化为称为函数值的对象。


查看完整回答
反对 回复 2019-06-05
  • 3 回答
  • 0 关注
  • 647 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信