表达式和语句之间有什么区别?

时间:2015-09-02 02:18:48

标签: expression

我知道这可能是重复的,但我没有找到足够的答案来解释我的例子。一般来说,语句和表达式之间有什么区别?这是一个我还没有完全区分的区别。我知道通常表达式应该是返回值的任何东西,例如文字或函数。语句通常被认为是口译员的命令,例如"打印这样的"或者"做。 。 。而&#34 ;.但是,我没有得到它。

说print是一个表达式是不是有道理,因为它是一个打印输入(输入到输出)的函数?此外,人们通常说x = 1是一个陈述,但是这不能被认为是一个表达式,其中赋值运算符是作用于两个输入的函数,输出是x指的是1?最后,不能用于流量控制结构,例如if。 。 。否则被认为是一个三参数函数,其中一个其他参数是根据第一个输入的真值返回的,使它成为一个表达式?

我可能很困惑,因为我有LISP的背景,一切都是表达。似乎我不能回避大多数编程结构都是其核心表达的想法。因此,有人可以解释一个所谓的陈述和表达之间真正的区别吗?

3 个答案:

答案 0 :(得分:8)

表达式语句的定义 - 即使存在一个或另一个 - 是特定于特定语言和描述它的语法

好吧,我们走吧:

  • 语句是一些“可评估代码” 1 不会出现在表达式上下文中;以及

  • 表达式是出现在上下文中的代码,通过替换表达式可以消除结果值

{一个非常宽松的'定义',但有没有一种语言。虽然有些语言对于副作用何时可以发生和不会发生是严格的 - 并且没有结果或副作用的代码是无用的 - 我不相信这样讨论是差异的基础。}

例如,让我们看看C中的printf。这是一个副作用and it returns a value的函数;通常会忽略返回值。因此printf可以同时显示为语句

printf("Hello world!");

和表达式

if (8 == printf("Hello %s!", name)) { // ..

(返回类型为void的函数调用只能 出现在C语句上下文中,但这是由类型系统强加的,而不是解析器。)

同样,请在JavaScript x = 1;x = (y = 2);中使用这两行。 x = ..是一个陈述,y = 2是一个产生值的表达式。

在这两个示例中,我们都看到语法生成确定它是被视为语句还是表达式。< / p>

相比之下,Ruby可以将“顶级”赋值视为表达式:

[1].map {|x| x = 2}

现在让我们看一个Python(2.x)的高峰。在这种情况下,print语句,这就是为什么这些工作分别不起作用的原因:

print "Look ma, no parenthesis!"
x = lambda y: print "Whoops!"       # invalid, print not an expression

if构造中,这些陈述或表达是什么?同样,它取决于特定的语言。在C和Java中,这些都是明确的陈述:没有办法使用诸如替代值。

另一方面,Scala(和Ruby)允许将这种流控制结构用作表达式,尽管它们也可以作为语句出现:

var emotionalResponse = if (color == "green") {
                          log.cheer()
                          new Cheering()
                        } else {
                          new Tears()
                        }

呼。那是很多 - 它并不是很全面。但是,回到可以重新考虑的“定义”,考虑上面的各种例子:

如果有问题的构造可以发生在需要值的地方(例如,在赋值的右侧,作为函数参数,作为另一个表达式的输入)那么它< em>可以被视为表达;并且绝对是在这样的背景下的表达。如果构造出现在不能通过替换访问的位置,那么它(或者更确切地说,可以作为)一个语句。

1 要处理的另一类产品是声明,例如C语言中的函数声明或Java中的类定义,并且可以说不是语句;因为以下内容已经非常分散,所以这是一个很重要的说明。

答案 1 :(得分:3)

表达式产生一个值,一个语句可以做某事。

例如;在C return a+5;中是一个语句,它退出一个函数,将从表达式a+5派生的值赋给调用者。

print是表达式还是声明取决于语言。

BASIC的印刷品不像功能一样,是由sompiler作为特殊情况处理的东西。类似pascal有writewriteln这些也是特殊情况,而不是函数calle,另一方面C有put()和printf()这两个函数。并允许程序员编写以相同方式工作的类似函数。

答案 2 :(得分:1)

答案更具哲学性而非实际性。陈述通常具有副作用,而表达本质上通常更具代数性。

在纯函数式语言中,没有语句。也就是说,甚至那些执行副作用(例如,对文件)的事物也用表示(理想地)所有突变的值表示 - 包括失败。

命令式语言利用语句执行任意代码,例如为变量赋值或打印到控制台,并可能通过异常传播传达失败。

纯粹的功能性表达只是通过将这些突变暴露为自身的价值来降低处理突变的认知开销。将其与模式匹配相结合,您将被迫显式处理所有成功和失败场景,从而将它们转换为值,显式映射或过滤任何失败。

不需要命令式语句将失败作为值公开,因此在毫无疑问的方法中总是存在任意代码存在的可能性,以至于容易被忽略。语句(例如方法调用或变量赋值(x = y = z()))通常可以适应表达式的模式,同时仍然执行任意代码并且无法将失败作为值进行通信。

最后,你无法避免突变。但是,您可以使其更明确。这意味着语句和表达主要以哲学方式不同,两者都存在以回答相同的问题 - 我们应该如何在代码执行的上下文中公开突变?