我问的是关于c#的问题,但我认为它在大多数其他语言中都是一样的。
有人对表达式和语句有很好的定义吗?它们的区别是什么?
我问的是关于c#的问题,但我认为它在大多数其他语言中都是一样的。
有人对表达式和语句有很好的定义吗?它们的区别是什么?
当前回答
表达式可以求值得到一个值,而语句不返回值(它们是void类型)。
当然,函数调用表达式也可以被视为语句,但除非执行环境有一个特殊的内置变量来保存返回值,否则无法检索它。
面向语句的语言要求所有过程都是语句列表。面向表达式的语言,可能是所有的函数式语言,都是表达式的列表,或者在LISP的情况下,是一个表示表达式列表的长s表达式。
尽管这两种类型都可以组合,但只要类型匹配,大多数表达式都可以任意组合。每种类型的语句都有自己的方式来组合其他语句,如果它们可以做到这一切的话。Foreach和if语句要么要求单个语句,要么要求所有子语句一个接一个地放入语句块中,除非子语句允许它们自己的子语句。
语句还可以包括表达式,而表达式实际上不包括任何语句。不过,lambda表达式是一个例外,它表示一个函数,因此可以包括函数可以包含的任何东西,除非语言只允许有限的lambdas,比如Python的单表达式lambdas。
在基于表达式的语言中,你所需要的只是一个函数的单个表达式,因为所有的控制结构都返回一个值(其中很多返回NIL)。不需要return语句,因为函数中最后求值的表达式就是返回值。
其他回答
我更喜欢“陈述”这个词的形式逻辑意义。它改变了计算中一个或多个变量的状态,从而能够对它们的值做出真或假的声明。
我想,当新的术语或词汇被引入,现有的词汇被“重新定义”,或者用户对他们所描述的现有的、已建立的或“适当的”术语一无所知时,在计算世界和科学中总会出现困惑
语句是表达式的一种特殊情况,具有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类型的表达式。
表达式
一段可以求值的语法。换句话说,表达式是表达式元素的累积,如字面量、名称、属性访问、操作符或函数调用,它们都返回一个值。与许多其他语言相比,并不是所有的语言结构都是表达式。还有一些语句不能用作表达式,比如while。赋值也是语句,而不是表达式。
声明
语句是套件(代码“块”)的一部分。语句可以是表达式,也可以是带有关键字的几个结构之一,如if、while或for。
语句是一段不返回任何东西的代码,它只是一个独立的执行单元。例如,
if(a>=0)
printf("Hello Humen,I'm a statement");
另一方面,表达式返回或计算一个新值。例如:
if(a>=0)
return a+10;//This is an expression because it evalutes an new value;
or
a=10+y;//This is also an expression because it returns a new value.
表达式是返回值的东西,而语句则不是。
例子:
1 + 2 * 4 * foo.bar() //Expression
foo.voidFunc(1); //Statement
两者之间的重要之处在于,您可以将表达式链接在一起,而语句则不能被链接。