我问的是关于c#的问题,但我认为它在大多数其他语言中都是一样的。
有人对表达式和语句有很好的定义吗?它们的区别是什么?
我问的是关于c#的问题,但我认为它在大多数其他语言中都是一样的。
有人对表达式和语句有很好的定义吗?它们的区别是什么?
当前回答
表达式
一段可以求值的语法。换句话说,表达式是表达式元素的累积,如字面量、名称、属性访问、操作符或函数调用,它们都返回一个值。与许多其他语言相比,并不是所有的语言结构都是表达式。还有一些语句不能用作表达式,比如while。赋值也是语句,而不是表达式。
声明
语句是套件(代码“块”)的一部分。语句可以是表达式,也可以是带有关键字的几个结构之一,如if、while或for。
其他回答
表达式
一段可以求值的语法。换句话说,表达式是表达式元素的累积,如字面量、名称、属性访问、操作符或函数调用,它们都返回一个值。与许多其他语言相比,并不是所有的语言结构都是表达式。还有一些语句不能用作表达式,比如while。赋值也是语句,而不是表达式。
声明
语句是套件(代码“块”)的一部分。语句可以是表达式,也可以是带有关键字的几个结构之一,如if、while或for。
语句是表达式的一种特殊情况,具有void类型。语言区别对待语句的倾向经常会导致问题,如果恰当地概括它们会更好。
例如,在c#中,我们有非常有用的Func<T1, T2, T3, TResult>重载泛型委托集。但是我们也必须有相应的Action<T1, T2, T3>集合,并且通用的高阶编程必须不断重复来处理这种不幸的分叉。
简单的例子——在调用另一个函数之前检查引用是否为空的函数:
TResult IfNotNull<TValue, TResult>(TValue value, Func<TValue, TResult> func)
where TValue : class
{
return (value == null) ? default(TValue) : func(value);
}
编译器能处理TResult为空的可能性吗?是的。它所要做的就是要求return后面跟着一个void类型的表达式。default(void)的结果将是void类型,传递的func将需要是func <TValue, void>(这将等效于Action<TValue>)的形式。
其他一些答案暗示你不能像连接表达式那样连接语句,但我不确定这个想法是从哪里来的。我们可以想到;它作为二进制中缀运算符出现在语句之后,取void类型的两个表达式并将它们组合成一个void类型的表达式。
语句->按顺序执行的指令 表达式->返回值的求值
语句基本上就像算法中的步骤或指令,语句执行的结果是指令指针的实现(所谓的汇编程序)。
表达式乍一看并不意味着和执行顺序,它们的目的是求值并返回值。在命令式编程语言中,表达式的求值是有顺序的,但这只是命令式模型的原因,而不是它们的本质。
语句示例:
for
goto
return
if
(所有这些都意味着执行的行(语句)提前到另一行)
表达式示例:
2+2
(这并不是指执行,而是指评估)
最准确地说,语句必须有“副作用”(即命令式),表达式必须有值类型(即不是底部类型)。
语句的类型是单元类型,但由于停止定理,单元是虚构的,所以我们说底层类型。
Void并不是最下面的类型(它不是所有可能类型的子类型)。它存在于没有完整的声音类型系统的语言中。这听起来可能有点势利,但是完整性(如方差注释)对于编写可扩展软件是至关重要的。
让我们看看维基百科对这件事是怎么说的。
https://en.wikipedia.org/wiki/Statement_ (computer_science)
在计算机编程中,语句是命令式编程语言中最小的独立元素,它表示要执行的某些操作。 许多语言(例如C语言)区分语句和定义,语句只包含可执行代码和声明标识符的定义,而表达式只计算值。
为了改进和验证我之前的回答,编程语言术语的定义应该从计算机科学类型理论中解释。
表达式具有除Bottom类型以外的其他类型,即它有一个值。语句具有Unit或Bottom类型。
由此可见,语句只有在产生副作用时才能在程序中发挥作用,因为它要么不能返回值,要么只返回Unit类型的值,而Unit类型的值要么不可赋值(在某些语言中,如C的void),要么可以存储以用于语句的延迟求值。
显然,@pragma或/*comment*/没有类型,因此与语句有所区别。因此,唯一没有副作用的语句类型是非操作。非手术治疗只能作为未来副作用的占位符。由于声明而采取的任何其他行动都是副作用。同样,编译器提示,例如@pragma,不是语句,因为它没有类型。