语句和函数之间的区别

12

现在快到午夜了,我突然有一个问题出现在脑海里,那就是“for循环”是语句还是函数。

我一直认为它是语句,但是我在谷歌上搜寻时发现也有称其为函数的结果。那么它到底是什么?在这种情况下,函数和语句之间有什么区别呢?


这真的取决于你使用的编程语言。是 Ruby、Python 还是 Javascript? - deceze
1
好问题——这表明你已经做了大量的研究,这非常重要。 - Purag
@deceze 这三种语言中不都是语句吗? - Corey Farwell
1
@Corey 如果我没记错的话,Ruby 中几乎所有的东西都是表达式。而在 Ruby 中最惯用的循环方法通常是使用对象的方法。但由于问题本身没有指定语言,我猜这应该是无关语言的,那么你会发现许多语言都不是上述情况。 - deceze
3个回答

19

一个 for 循环不是通常意义下的函数,它是一种特殊的语句,称为流程控制结构。

语句 是一条命令。它执行某些操作。在大多数编程语言中,语句不返回值。例如:

print "Hello World"

函数是程序中的子程序,可以在程序的其他地方调用。函数通常(但不一定)返回值。例如:

function(a) { return a * 2 }

一个控制结构,也被称为复合语句,是用于指导执行流程的语句。例如:

if (condition) then { branch_1 } else { branch_2 }

for (i = 0; i < 10; i += 1) { ... }

值得注意的是,表达式是一段代码,它会求出一个值。例如:
2 + 2

所有示例均为伪代码,不与任何特定语言相关。还要注意这些不是互斥的类别,它们可以重叠。


1
按照这个逻辑,那么for循环既是语句又是控制结构,对吗?函数并不需要返回值——它也可以用于简单执行,但是以某种方式进行,其中某些内容是可变的,并且产品基于特定情况。 - Purag
错误地说一个for循环既不是语句也不是函数是不正确的(并不是它不能用作控制结构)。在大多数编程语言中,for循环是一个复合语句,尽管它也可以是表达式或函数。在Javascript、Python和Ruby中,它是一个语句。 - Zach Kelling
复合语句和函数有什么区别? - madLokesh
@madLokesh,“复合语句”只是“控制结构”的另一个名称。它只是控制执行流程的语句(之所以称为“复合”,是因为它与普通语句不同--控制结构的主体由更多语句组成)。 - Ben Lee
1
@GeorginaDavenport 函数的定义作为从域到范围的映射更多地是一个严格的数学定义。在计算机科学中,“函数”通常只是“子例程”的同义词,具体取决于语言是否返回任何值。此外,与数学函数不同,在大多数语言中,没有限制给定输入将始终返回相同的输出。实际上,对于某些函数来说,这就是它们的明确目的(例如,“Time.now()”函数可能会根据一天中的时间返回不同的值)。 - Ben Lee
显示剩余8条评论

8

您选择的三个语言标签中,我只熟悉Python,但我相信许多其他编程语言对这些概念有类似的看法。这里的所有示例代码都是Python。

语句是一个被执行的东西;一种语言实现可以理解的“做某事的指令”。例如:

print "Hello World"

pass

def foo(n):
    return n + 1

if condition:
    print 'yay'
else:
    print 'doh'

上面的代码块包含一个打印语句,一个pass语句,一个函数定义语句和一个if/else语句。注意,函数定义和if/else语句都是复合语句;它们包含其他语句(可能有许多语句,也可能有其他复合语句)。

表达式是可以求值以产生值的东西。例如:

1

"foo"

2 * 6

function(argument)

None

以上内容包含数字字面表达式、字符串字面表达式、涉及数字运算符的表达式、函数调用表达式和字面None表达式。除了字面量和变量,表达式由其他表达式组成。在function(argument)中,functionargument也都是表达式。
关键的区别在于语句是指示语言实现去执行某些操作的指令。表达式则被计算出一个值(这可能需要语言实现在过程中去执行某些操作)。
这导致了一个后果,即你可以在任何看到值的地方(包括表达式),替换为任何其他表达式,你仍然会得到某种有意义的东西。它可能无法编译,或在运行时抛出异常,但至少在某种程度上你可以理解发生了什么。
语句绝对不能出现在表达式中(我认为在Ruby和Javascript中,它们允许使用代码块和函数作为整体值的文字,函数和代码块包含语句;但这与我的讨论有所不同)。表达式必须有一个值(即使它是像None这样毫无趣味的值)。语句是一条命令,它没有值,因此它在表达式的一部分中是没有意义的。
许多语言也允许将表达式用作语句。通常的含义是“计算此表达式以获取一个值,然后丢弃它”。在Python中,总是返回None的函数通常以这种方式使用:
write_to_disk(result)

它被用作“命令”,看起来像一个语句,但从技术上讲,它是一个表达式,我们只是不使用它计算的值。你可以认为“裸表达式”是语言中可能的语句之一(它们通常这样解析)。
有些语言区分必须像没有返回值的语句一样使用的函数(通常称为过程)和像表达式一样使用的函数,并且对于将函数用作语句,会给出错误或警告,并且绝对会因使用过程作为表达式而出错。
因此,如果foo是一个表达式,我可以写1 + foo,虽然它可能会导致类型错误,但至少意义上是正确的。如果foo是一个语句,那么1 + foo通常是一个解析错误。语言实现甚至无法理解你试图说什么。
另一方面,函数是可以调用的东西。它本身既不是表达式也不是语句。在Python中,您使用def语句创建一个函数,函数调用是一个表达式。创建函数后绑定到函数的名称也是一个表达式。但是函数本身是一个,从技术上讲它不完全是一个表达式,但肯定不是语句。
那么,对于循环。这是Python中的一个for循环:
for thing in collection:
    do_stuff(thing)

看起来像是一个语句(复合语句,比如if语句)。为了证明这一点,以下内容毫无意义(并且是解析错误):

1 + for thing in collection:
    do_stuff(thing)

在某些语言中,for循环的等价物是一个表达式,并且具有一个值,您可以尝试将其加1。在某些语言中,它甚至是一个函数,而不是内置于语言中的特殊语法。

“一个语句永远不可能出现在表达式中(我相信这在 Ruby 中不是真的[...])” - Ruby 没有语句,只有表达式。 - Jörg W Mittag
@JörgWMittag 那么for循环的价值是什么?快速谷歌了一下Ruby语法,似乎没有返回值,除了作为代码块的意义外。一个表达式被评估为“代码值”,而要执行的声明似乎是不同的东西,即使是相同的原始文本在源代码中也可能表示任一内容,具体取决于上下文; 我现在正在处理这个问题,在一个我平常开发的玩具语言中。 - Ben
@JörgWMittag 我又读了一些资料,我发现你说的并不是那个意思。Ruby确实会给循环、条件语句等赋值。很棒!但是还有一些东西在语义上确实是语句,比如break(有时候Ruby会因为将它们用作表达式而给出解析错误,但并非总是:http://carboni.ca/blog/p/Statements-in-Ruby)。 - Ben

1

这篇答案与Python 2.7.2相关。摘自python教程

"4. 更多控制流工具

4.2. for语句: Python中的for语句与C或Pascal中您可能习惯的有些不同。Python的for语句迭代任何序列(列表或字符串)中出现的项目,按它们在序列中出现的顺序进行迭代,而不总是迭代数字的算术进度(如Pascal中),或者给用户定义迭代步骤和停止条件的能力(如C中)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接