3 回答
TA贡献1802条经验 获得超6个赞
首先,让我们看看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 ""
我认为这几乎涵盖了一切,但我很乐意用任何问题的答案来补充这一点。
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
TA贡献1865条经验 获得超7个赞
功能可以使用参数列表调用函数以生成结果。函数具有参数列表、主体和结果类型。作为类、特征或单例对象的成员的函数被调用。方法..在其他函数中定义的函数称为局部函数。带有结果类型Unit的函数称为过程。源代码中的匿名函数称为函数文本。在运行时,函数文本被实例化为称为函数值的对象。
添加回答
举报