“过程”的“正确”定义是什么, “方法”,“功能”,“子程序”等?
#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
评论
您放弃“常规”@teresko:我认为“子程序”更为常见。