这个问题很简单,但是我经常听到这三个术语定义得如此残酷,但多年来我知道这些术语的含义有所不同。
“过程”,“方法”,“函数”,“子例程”等的“正确”定义是什么?
这个问题很简单,但是我经常听到这三个术语定义得如此残酷,但多年来我知道这些术语的含义有所不同。
“过程”,“方法”,“函数”,“子例程”等的“正确”定义是什么?
Answers:
我在这里有一个不同的答案:实际上,实际上并没有什么区别,只是有一点例外,即“方法” 通常是指与OO语言中与对象关联的子例程。
术语“过程,函数,子例程,子程序和方法”实际上都具有相同的含义:较大程序中的可调用子程序。但是很难提出一个定义来捕获这些术语的所有变体用法,因为它们在各种编程语言或范式中使用的不一致。
您可能会说一个函数返回一个值。好吧,以下C函数不会返回值:
void f() { return; }
...但是我怀疑您会发现有人将其称为过程。
当然,在Pascal中,过程不会返回值,而函数会返回值,但这仅是Pascal设计方式的反映。在Fortran中,一个函数返回一个值,而子例程返回多个值。然而,这些都没有真正允许我们为这些术语提供一个“通用”定义。
实际上,术语“过程编程”是指一整类语言,包括C,Fortran和Pascal,其中只有一种实际上使用术语“过程”来表示任何东西。
因此,这些都不是真正一致的。唯一的例外可能是“方法”,它似乎几乎完全与OO语言一起使用,指代与对象关联的功能。虽然,但这并不总是一致的。例如,C ++通常使用术语“成员函数”而不是方法,(即使术语“方法”已在程序员中逐渐渗透到C ++语言中。)
关键是,这些都不是真正一致的。它只是反映了当时流行的任何语言所使用的术语。
一个函数返回一个值,而是一个程序没有。
甲方法类似于函数,但是内部类的一部分。术语“ 方法”几乎专门用于面向对象的编程中。
function
在JS中同时扮演这两个角色当然是正确的,但是JS函数会全部返回。当return语句没有值时,该值是隐式的undefined
。当没有return语句时,解释器将添加一个隐式return语句。也许很深奥,但这与此处给出的定义一致。这就是为什么var x = function() {}();
在JS中合法的原因;如果不是隐式的回报,那将是一个错误,就像在Pascal中那样。
甲功能是一些把一束输入,并返回一个或多个值。如果返回的值完全由输入确定,并且该函数没有任何副作用(可能记录日志,或者导致其自身外部发生状态更改),则该函数称为纯函数。
一个方法是不返回值的函数。特别是,这意味着一个过程只能引起副作用。(这可能包括更改输入参数!)
甲方法是封闭在一组变量,即,一个功能关闭。它接受零个或多个输入参数,可以访问此变量集,并返回零个或多个值。在OO语言中,这些方法被附加到对象或类上。
在大多数主流的OO语言中,那些封闭的变量称为对象的成员字段或实例变量。方法可以是纯函数,不纯函数或过程。
后面的定义导致对象=结构+闭包的对应关系。
foo.doSomething()
不是无参数的。它具有一个参数(对象foo
),并带有一些语法糖。闭包将能够引用其对象而无需此类参数。这并不是说方法不能是闭包,只是大多数不能,而且面向对象不足以使语言支持闭包。
foo.doSomething()
关闭foo
变量。中的任何语句都doSomething
可以foo
通过this
或进行访问self
,具体取决于您的语言。这就是“封闭”的定义。类关闭其成员变量,因此(忽略“ OO是什么”),OO就足够了。这在文献中是众所周知的...
foo.
前面的那一点foo.doSomething()
吗?那是您传递doSomething()
参数。仅仅因为它不在括号之间并不意味着它不是参数。方法中的this
or self
内部仅是用于引用该参数的语法糖。
布鲁斯有一个很好的答案。我会在语义上添加:
printf
)A procedure should "do something" to the arguments
-或引起其他副作用(例如printf
)。
printf
返回一个值-打印的字符数-因此从技术上讲它是一个函数。
printf
是一个价值。它在调用范围之外有一个特定的副作用:即无论标准输出是什么,都应该是I / O。即使Scott并没有明确区分这种区别,在函数式编程中函数也不应该具有副作用,并且应该能够像回答返回的实际数据一样回答问题。
80%的熟练程度与对术语的熟悉程度直接相关,
95%的生产力是能够识别当前有用的功能,尽管用术语来描述它
我非常喜欢用c#调用它们的所有方法,除了在使用MSSQL时我们使用了sproc的时候,但是当然现在我们使用Postgres,它们被称为函数。