Scala中方法和函数的区别

Scala中方法和函数的区别

我读Scala函数(部分)又一次斯卡拉之旅)。在该职位上,他说:

方法和函数不是一回事。

但他没有解释这件事。他想说什么?


胡子哥哥
浏览 687回答 3
3回答

呼啦一阵风

首先,让我们看看Scala规范告诉我们什么。第三章(类型)告诉我们功能类型(3.2.9)和方法类型(3.3.1)。第四章(基本宣言)谈到价值宣言和定义 (4.1), 可变声明和定义(4.2)和函数声明和定义(4.6)。第六章(词组)谈到匿名函数(6.23)和方法值(6.7)。奇怪的是,函数值只在3.2.9上提到过一次,而在其他地方则没有。A 功能类型(大致上)是表单的一种类型。(T1,.,TN)=>U,这是特征的缩写。FunctionN在标准图书馆里。匿名函数和方法值有函数类型,函数类型可以用作值、变量和函数声明和定义的一部分。实际上,它可以是方法类型的一部分。A 方法类型是非值型..这意味着不值-没有对象,没有实例-具有方法类型。如上文所述,a方法值实际上有一个功能类型..方法类型是def声明-关于def除了它的身体。价值声明和定义和变量声明和定义是val和var声明,包括两者类型和价值-分别可以是,功能类型和匿名函数或方法值..注意,在JVM上,这些(方法值)是用Java所称的“方法”实现的。A 功能声明是def声明,包括类型和体体..类型部分是方法类型,而主体是表达式或块..这也是用Java所谓的“方法”在JVM上实现的。最后,匿名函数是功能类型(特征的一个例子)FunctionN),以及方法值都是一样的!区别在于方法值是通过后置下划线(m _是对应于“函数声明”的方法值(def) m),或者通过一个名为ETA-扩张,这就像一种从方法到功能的自动转换。规格是这么说的,所以让我把这个放在最前面:我们不使用这个术语!这会导致所谓的混乱“功能声明”,这是程序的一部分(第4章-基本声明)和“匿名函数”,这是一个表达式,并且“功能类型”这是一种类型-一种特质。以下术语和经验丰富的Scala程序员使用的术语与规范的术语有一处不同:而不是说功能声明,我们说方法..甚至方法声明。此外,我们注意到价值声明和变量声明也是实用的方法。因此,考虑到上述术语的变化,下面是对这一区别的实用解释。A 功能是一个对象,该对象包括FunctionX特征,如Function0, Function1, Function2等可能包括PartialFunction也是,这实际上扩展了Function1.让我们看看其中一个特征的类型签名:trait Function2[-T1, -T2, +R] extends AnyRef这个特性有一个抽象的方法(它也有一些具体的方法):def apply(v1: T1, v2: T2): R这告诉了我们所有需要知道的事情。一个功能有一个apply接收N类型参数t1, T2, ..., 总氮,并返回某种类型的东西。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 ""我认为这几乎涵盖了一切,但我很乐意用任何问题的答案来补充这一点。

湖上湖

方法和函数之间的一个很大的实际区别是return手段。return只有从方法中返回。例如:scala>&nbsp;val&nbsp;f&nbsp;=&nbsp;()&nbsp;=>&nbsp;{&nbsp;return&nbsp;"test"&nbsp;}<console>:4:&nbsp;error:&nbsp;return&nbsp;outside&nbsp;method&nbsp;definition&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;val&nbsp;f&nbsp;=&nbsp;()&nbsp;=>&nbsp;{&nbsp;return&nbsp;"test"&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;^从方法中定义的函数返回非本地返回:scala>&nbsp;def&nbsp;f:&nbsp;String&nbsp;=&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;val&nbsp;g&nbsp;=&nbsp;()&nbsp;=>&nbsp;{&nbsp;return&nbsp;"test"&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;g()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;"not&nbsp;this" &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;}f:&nbsp;Stringscala>&nbsp;f res4:&nbsp;String&nbsp;=&nbsp;test而从本地方法返回只能从该方法返回。scala>&nbsp;def&nbsp;f2:&nbsp;String&nbsp;=&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;def&nbsp;g():&nbsp;String&nbsp;=&nbsp;{&nbsp;return&nbsp;"test"&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;g() &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;"is&nbsp;this" &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;}f2:&nbsp;Stringscala>&nbsp;f2 res5:&nbsp;String&nbsp;=&nbsp;is&nbsp;this

鸿蒙传说

功能可以使用参数列表调用函数以生成结果。函数具有参数列表、主体和结果类型。作为类、特征或单例对象的成员的函数被调用。方法..在其他函数中定义的函数称为局部函数。带有结果类型Unit的函数称为过程。源代码中的匿名函数称为函数文本。在运行时,函数文本被实例化为称为函数值的对象。
打开App,查看更多内容
随时随地看视频慕课网APP