Function Type (大致)是一种形式(T1,...,Tn)=> U,它是标准库中特征 FunctionN 的简写 . Anonymous Functions 和 Method Values 具有函数类型,函数类型可以用作值,变量和函数声明和定义的一部分 . 实际上,它可以是方法类型的一部分 .
Method Type 是 non-value type . 这意味着有一个 no 值 - 没有对象,没有实例 - 带有方法类型 . 如上所述, Method Value 实际上有 Function Type . 方法类型是一个 def 声明 - 除了它的主体之外的所有关于_785622的声明 .
Value Declarations and Definitions 和 Variable Declarations and Definitions 是 val 和 var 声明,包括类型和值 - 分别可以是 Function Type 和 Anonymous Functions or Method Values . 请注意,在JVM上,这些(方法值)是使用Java调用"methods"实现的 .
Function Declaration 是 def 声明,包括类型和正文 . 类型部分是方法类型,主体是表达式或块 . 这也是在JVM上实现的,Java调用"methods" .
最后, Anonymous Function 是 Function Type 的实例(即特征的实例 FunctionN ), Method Value 是同一个东西!区别在于方法值是从方法创建的,可以通过后缀下划线( m _ 是对应于"function declaration"( def ) m 的方法值),也可以通过称为eta-expansion的过程创建,这类似于方法的自动转换发挥作用 .
这就是规范所说的,所以让我把它放在前面: we do not use that terminology! 它导致所谓的"function declaration"之间的混淆,这是程序的一部分(第4章 - 基本声明)和"anonymous function",这是一个表达式和"function type",这是一种类型 - 特征 .
下面的术语,由经验丰富的Scala程序员使用,从规范的术语进行了一处更改: instead of saying function declaration, we say method . 甚至方法声明 . 此外,我们注意到值声明和变量声明也是实用的方法 .
So, given the above change in terminology, here's a practical explanation of the distinction.
6 回答
吉姆在his blog post中已经涵盖了这个,但我在这里发布简报以供参考 .
首先,让我们看看Scala规范告诉我们的内容 . 第3章(类型)告诉我们函数类型(3.2.9)和方法类型(3.3.1) . 第4章(基本声明)涉及 Value 声明和定义(4.1),变量声明和定义(4.2)以及函数声明和定义(4.6) . 第6章(表达式)讲的是匿名函数(6.23)和方法值(6.7) . 奇怪的是,功能值在3.2.9中被说出一次,而在其他地方则没有 .
Function Type (大致)是一种形式(T1,...,Tn)=> U,它是标准库中特征
FunctionN
的简写 . Anonymous Functions 和 Method Values 具有函数类型,函数类型可以用作值,变量和函数声明和定义的一部分 . 实际上,它可以是方法类型的一部分 .Method Type 是 non-value type . 这意味着有一个 no 值 - 没有对象,没有实例 - 带有方法类型 . 如上所述, Method Value 实际上有 Function Type . 方法类型是一个
def
声明 - 除了它的主体之外的所有关于_785622的声明 .Value Declarations and Definitions 和 Variable Declarations and Definitions 是
val
和var
声明,包括类型和值 - 分别可以是 Function Type 和 Anonymous Functions or Method Values . 请注意,在JVM上,这些(方法值)是使用Java调用"methods"实现的 .Function Declaration 是
def
声明,包括类型和正文 . 类型部分是方法类型,主体是表达式或块 . 这也是在JVM上实现的,Java调用"methods" .最后, Anonymous Function 是 Function Type 的实例(即特征的实例
FunctionN
), Method Value 是同一个东西!区别在于方法值是从方法创建的,可以通过后缀下划线(m _
是对应于"function declaration"(def
)m
的方法值),也可以通过称为eta-expansion的过程创建,这类似于方法的自动转换发挥作用 .这就是规范所说的,所以让我把它放在前面: we do not use that terminology! 它导致所谓的"function declaration"之间的混淆,这是程序的一部分(第4章 - 基本声明)和"anonymous function",这是一个表达式和"function type",这是一种类型 - 特征 .
下面的术语,由经验丰富的Scala程序员使用,从规范的术语进行了一处更改: instead of saying function declaration, we say method . 甚至方法声明 . 此外,我们注意到值声明和变量声明也是实用的方法 .
So, given the above change in terminology, here's a practical explanation of the distinction.
函数是一个包含
FunctionX
特征之一的对象,例如Function0
,Function1
,Function2
等 . 它也可能包括PartialFunction
,它实际上扩展了Function1
.让我们看看其中一个特征的类型签名:
这个特性有一个抽象方法(它也有一些具体的方法):
这告诉我们所有人都应该了解它 . 函数有一个
apply
方法,它接收类型为T1,T2,...,TN的N个参数,并返回R
类型的东西 . 它在接收的参数上是反变量的,并且在结果上是共变量 .该差异意味着
Function1[Seq[T], String]
是Function1[List[T], AnyRef]
的子类型 . 作为子类型意味着它可以用来代替它 . 人们可以很容易地看到,如果我打算调用f(List(1, 2, 3))
并期望AnyRef
返回,则上述两种类型中的任何一种都可以工作 .现在,方法和函数的相似性是什么?好吧,如果
f
是一个函数而m
是作用域的本地方法,则可以像这样调用它们:这些调用实际上是不同的,因为第一个只是一个语法糖 . Scala将其扩展为:
当然,这是对对象
f
的方法调用 . 函数还有其他语法糖的优势:函数文字(其中两个,实际上)和(T1, T2) => R
类型签名 . 例如:方法和函数之间的另一个相似之处是前者可以很容易地转换为后者:
Scala将扩展它,假设
m
类型是(List[Int])AnyRef
into(Scala 2.7):在Scala 2.8上,它实际上使用
AbstractFunction1
类来减少类的大小 .请注意,无法转换其他方式 - 从函数到方法 .
然而,方法有一个很大的优点(好吧,两个 - 它们可以稍快一点):它们可以接收类型参数 . 例如,虽然上面的
f
必须指定它接收的List
的类型(在示例中为List[Int]
),m
可以对其进行参数化:我认为这几乎涵盖了一切,但我很乐意补充这可以回答任何可能存在的问题 .
方法和函数之间的一个重大实际区别是
return
的含义 .return
只从方法返回 . 例如:从方法中定义的函数返回非本地返回:
而从本地方法返回只从该方法返回 .
Programming in Scala Second Edition. Martin Odersky - Lex Spoon - Bill Venners
假设你有一个清单
定义方法
定义一个函数
接受论证的方法
用val定义函数
功能参数是可选的
对方法的争论是强制性的
检查以下Tutorial,解释通过其他示例传递其他差异,例如使用方法Vs函数的diff的其他示例,使用函数作为变量,创建返回函数的函数
函数不支持参数默认值 . 方法呢 . 从方法转换为函数会丢失参数默认值 . (Scala 2.8.1)
有一篇很好的文章here,我的大部分描述都是从这篇文章中提取的 . 只是简单比较一下我理解的功能和方法 . 希望能帮助到你:
Functions :它们基本上是一个对象 . 更确切地说,函数是具有apply方法的对象;因此,由于它们的开销,它们比方法慢一点 . 它类似于静态方法,因为它们独立于要调用的对象 . 一个简单的函数示例就像下面这样:
除了将一个对象分配给另一个对象(如object1 = object2)之外,上面的行就没有了 . 实际上我们示例中的object2是一个匿名函数,左侧因此得到了一个对象的类型 . 因此,现在f1是一个对象(Function) . 匿名函数实际上是Function1 [Int,Int]的一个实例,它表示一个函数,其中一个参数类型为Int,返回值类型为Int . 在没有参数的情况下调用f1将为我们提供匿名函数的签名(Int => Int =)
Methods :它们不是对象,而是分配给类的实例,即对象 . 与java中的方法或c中的成员函数完全相同(在this question的注释中指出Raffi Khatchadourian)等等 . 方法的一个简单示例就像下面这样:
上面的行不是简单的值赋值,而是方法的定义 . 当您使用值2调用此方法时,如第二行,x将替换为2,结果将被计算,您将获得4作为输出 . 如果只是简单地编写m1就会出现错误,因为它是方法并且需要输入值 . 通过使用_,您可以将方法分配给类似下面的函数: