这是一个简单的问题,但是我经常听到这三个术语定义得如此残酷,但多年来我都知道它们具有不同的含义。

“过程”的“正确”定义是什么, “方法”,“功能”,“子程序”等?

评论

您放弃“常规”

@teresko:我认为“子程序”更为常见。

#1 楼

我在这里有一个不同的答案:实际上,实际上并没有什么区别,只是有一点例外,“方法”通常是指与OO语言中的对象相关联的子例程。

术语“过程,函数,子例程,子程序和方法”实际上意味着同一件事:在较大程序中的可调用子程序。但是很难提出一个定义来捕获这些术语的所有变体用法,因为它们在各种编程语言或范式中使用的不一致。

您可能会说函数返回一个值。好吧,以下C函数不会返回值:

void f() { return; }


...但是我怀疑您会发现有人将其称为过程。

当然,在Pascal中,过程不返回值,而函数返回值,但这仅是Pascal设计方式的反映。在Fortran中,一个函数返回一个值,而子例程返回多个值。但是,这些都没有真正允许我们为这些术语提供一个“通用”定义。

实际上,术语“过程编程”是指一整类语言,包括C,Fortran和Pascal,其中只有一个实际上使用“过程”一词来表示任何东西。

因此,这些都不是真正一致的。唯一的例外可能是“方法”,它似乎几乎完全与OO语言一起使用,指代与对象关联的功能。虽然,但这并不总是一致的。例如,C ++通常使用术语“成员函数”而不是方法,(即使术语“方法”已经在程序员中流传到C ++了。)

重点是,这些都不是确实是一致的。它只是反映了当时流行的任何语言所使用的术语。

评论


这正是我以为的答案。 (事后看来,我应该添加“子例程”作为另一个变体。)我可以问:为什么您找不到找到将C函数称为“过程”的人?是因为技术上不正确,还是因为“过程”一词目前不流行?

– Django Reinhardt
10 Nov 23 '19:42



C程序员使用术语“函数”仅仅是因为C的设计师使用了该术语。

–查尔斯·萨尔维亚
2010-11-23 19:54

让我们不要把婴儿和洗澡水一起扔出去。仅仅因为术语使用不完全一致,并不意味着不同的术语没有不同的含义。 @Bruce和@Frank的定义是公认的,而不是特质的。含义不是通用的这一事实很重要,但是它并不能证明向“实际而言,实际上没有区别”的飞跃。 (@Django)

– LarsH
10 Nov 23 '23:33



C ++的对偶类型,将方法称为“成员函数”,而Java和C#则将函数称为“静态方法”。

–Jörg W Mittag
10 Nov 24'1:28

如果您是编程新手,Bruce的答案肯定是您应该寻求的答案。他的定义在99%的时间内都是绝对正确的。但是我一直在寻找更多的技术/理论答案。有时,较新的程序员仅了解自己的领域,并坚持这就是全部。实际上,今天有工作的程序员仍在使用较旧的语言,并且使用不同的定义并非“错误”。那是我最感兴趣的。

– Django Reinhardt
2011年4月12日在18:37

#2 楼

函数返回值,但过程不返回。

方法类似于函数,但属于类的一部分。方法一词几乎专门用于面向对象的编程中。

评论


不完全是内部的。方法是属于类的任何函数或过程。

–斯科特·惠特洛克
2010-11-23 17:48



因此,SQL中的“存储过程”不会返回任何值吗?像Pascal这样的“程序”呢?您的定义是基于当前趋势还是应该被认为是通用定义?谢谢!

– Django Reinhardt
2010-11-23 19:10

@Django:在Pascal中,过程不能具有返回值,而函数必须具有返回值。在其他一些语言中,该术语的使用可能更宽松。

–布鲁斯·奥尔德曼(Bruce Alderman)
2010-11-23 20:04

FWIW,FORTRAN从早期开始就有SUBROUTINE和FUNCTIONS,区别在于SUBROUTINE没有返回值。我不记得Pascal的起源于ALGOL。

– David Thornley
2010-11-23 22:42

@ 3p1c_d3m0n函数确实可以在JS中同时扮演这两个角色,但是JS函数会全部返回。当return语句没有值时,该值是隐式未定义的。当没有return语句时,解释器将添加一个隐式return语句。也许很深奥,但这与此处给出的定义一致。这就是为什么var x = function(){}();在JS中是合法的;如果不是隐式收益,那将是一个错误,就像在Pascal中那样。

–分号
2015年11月8日,下午5:25

#3 楼

函数是需要一堆输入并返回一个或多个值的东西。如果返回的值完全由输入确定,并且该函数没有任何副作用(可能记录日志,或者导致其自身外部发生状态更改),则该函数称为纯函数。

A过程是不返回值的函数。特别是,这意味着一个过程只能引起副作用。 (这可能包括更改输入参数!)

方法是一种对一组变量(即闭包)进行封闭的函数。它接受零个或多个输入参数,可以访问此变量集,并返回零个或多个值。在OO语言中,这些方法是附加到对象或类上的。

在大多数主流的OO语言中,这些封闭的变量称为对象的成员字段或实例变量。方法可以是纯函数,不纯函数或过程。

后一种定义导致对象= struct +闭包的对应关系。

评论


因此,对象是变量的集合以及这些公共变量的闭包的集合。基本上,面向对象的语言一直都有闭包,没人知道吗?有趣的观点! +1

–乔治
13年1月4日23:45



我认为大多数方法都无法解决任何问题。 foo.doSomething()不是无参数的。它具有一个参数(对象foo),并带有一些语法糖。闭包将能够引用其对象而无需此类参数。这并不是说方法不能是闭包,只是大多数不能,而且面向对象不足以使语言支持闭包。

– 8bittree
2014年8月14日20:43



foo.doSomething()关闭foo变量。 doSomething中的任何语句都可以通过this或self来访问foo,具体取决于您的语言。这就是“封闭”的定义。类关闭其成员变量,因此(忽略“ OO是什么”),OO就足够了。这在文献中是众所周知的。

–坦率的剪毛
14年8月15日在8:47

呃没有。看到那个小傻瓜。在foo.doSomething()的前面?那就是您传递doSomething()参数。仅仅因为它不在括号之间并不意味着它不是参数。方法内部的this或self只是引用该参数的语法糖。

– 8bittree
16年6月9日在16:54



@FrankShearar,我想说在计算中只有两个相当明显的区别:数据和指令。在(非常规)自修改代码的情况下,即使是这样,也是如此。在OO中,通常所说的“方法”(或“成员函数”)不必是您定义的方法或函数-所有这些常用的词实际上都是具有通用且可互换含义的同义词。您所暗示的“不纯函数”只是同一“指令”一般概念的另一个(也是最冗长的术语)。

–史蒂夫
18年2月6日在17:48

#4 楼

布鲁斯有一个很好的答案。我会在语义上添加:


过程应该对参数“做某事”或引起其他副作用(例如printf
函数应(a)回答a有关参数的问题,或(b)根据参数计算新值
函数方法应回答有关对象状态的问题
过程方法应更改对象状态的问题


评论


好答案!只是增加了一点点:过程应该对参数“做某事”-或引起其他副作用(例如printf)。

– Allon Guralnek
2010-11-23 18:05



@Allon请注意,printf返回一个值-打印的字符数-因此从技术上讲它是一个函数。

– Sjoerd
2011年4月12日在20:09

@Sjoerd我不同意printf是一个值。它在调用范围之外有一个特定的副作用:即无论标准输出是什么,都应该是I / O。即使Scott并没有明确区分这种区别,但在函数式编程中,函数不应产生副作用,并且应该能够像回答返回的实际数据一样回答问题。

–艾伦
14年8月14日在17:17

#5 楼

上面有很好的详细答案;简短的故事是,它们将包含所有子例程。每个术语的含义将根据编程语言的上下文而变化。

通常,函数返回值,但是它们不必

方法是通用的OOP。当前的术语

在SQL中,存储过程具有输出,但通常仅返回错误代码,而用户定义的函数必须返回值(可能是结果集)

再次,这些术语之间的确切区别取决于您在和谁说话!

#6 楼

80%的熟练程度与对术语的熟悉程度直接相关。

95%的生产率是能够识别当前有用的功能,尽管有术语来描述它

我非常喜欢在c#中调用它们的所有方法,除了在使用MSSQL时我们使用了sproc的时候,但是当然现在我们使用Postgres,它们被称为函数。

评论


所有统计的83.5%是当场构成;-P

– Django Reinhardt
13年5月5日在5:22

我必须承认,当我听到有人使用非OO语言工作时会抛出“方法”一词时,我会感到紧张。它似乎与运行非惯用代码密切相关。

– Racheet
2014年1月17日15:54

当我指的是C代码时,我使用“方法”,因为与我打交道的许多OO程序员在听过术语过程或函数时都有精神上的崩溃。为了娱乐,如果我真的想弄乱它们,我可能会随机互换这些术语。不好,有点像邀请一位讲故事的人进入您的家... :)

–mattnz
2014年7月7日在1:46