Ruby中语句和表达的区别是什么?

时间:2012-03-09 15:21:54

标签: ruby expression

我知道在Ruby中,几乎所有东西都是表达式。甚至那些使用其他语言的语句,如if-else语句,case语句,赋值语句,循环语句也是Ruby中的表达式。

所以我想从Ruby的观点来看,语句和表达之间的区别是什么?

4 个答案:

答案 0 :(得分:4)

表达式之间没有区别,语句是Ruby。一切都评估为一个值,所以一切都是表达。

答案 1 :(得分:2)

来自Ruby hacking guide

  

此外,函数和类定义通常是语句,例如Lisp和Scheme,因为一切都是表达式,它们首先没有语句。在这方面,Ruby接近Lisp的设计。

这些是语句的语法规则,您可以在其中看到(某种程度上)语言实现中的语句。请注意 expr 规则,这意味着stmnt可以是expr。 expr不能是stmt。

stmt        : kALIAS fitem  fitem
            | kALIAS tGVAR tGVAR
            | kALIAS tGVAR tBACK_REF
            | kALIAS tGVAR tNTH_REF
            | kUNDEF undef_list
            | stmt kIF_MOD expr_value
            | stmt kUNLESS_MOD expr_value
            | stmt kWHILE_MOD expr_value
            | stmt kUNTIL_MOD expr_value
            | stmt kRESCUE_MOD stmt
            | klBEGIN ‘{’ compstmt ‘}’
            | klEND ‘{’ compstmt ‘}’
            | lhs ‘=’ command_call
            | mlhs ‘=’ command_call
            | var_lhs tOP_ASGN command_call
            | primary_value ‘[’ aref_args ‘]’ tOP_ASGN command_call
            | primary_value ‘.’ tIDENTIFIER tOP_ASGN command_call
            | primary_value ‘.’ tCONSTANT tOP_ASGN command_call
            | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_call
            | backref tOP_ASGN command_call
            | lhs '=' mrhs_basic
            | mlhs '=' mrhs
            | expr

答案 2 :(得分:1)

将表达式视为句子的一小部分。将该陈述视为已完成的句子或思想。你的方法或循环中的一行可以是一个表达式,这些表达式集合成一个闭环或方法可以被认为是一个陈述。

这或多或少在概念上是主观的。正如Niklas B.正确地指出的那样(你正确地注意到了)。

您是否有直接处理的问题让您对此有所了解?

你也会听到人们说“红宝石中的一切都是一个对象”,而不是一切都是表达。

答案 3 :(得分:0)

有区别。这是一个微妙但重要的。表达式是一种语句。所有表达式都是语句,但并非所有语句都是表达式。

最值得注意的是,不是表达式的语句包括:

stmt if expr
stmt unless expr
stmt while expr
stmt until expr
stmt rescue expr
var = method expr
x,y = expr

当用作修饰语时,ifelsewhileuntilrescue成为 语句,而不是表达式。这意味着它们不能在以下情况下使用 需要一个表达式,例如方法参数。用括号包裹 创建一个表达式。

  puts( 1 if true )      #=> SyntaxError
  puts((1 if true))      #=> 1
  puts (1 if true)       #=> 1, because of optional parentheses for method

  puts( 1 rescue true )  #=> SyntaxError
  puts((1 rescue true))  #=> 1
  puts (1 rescue true)   #=> 1, because of optional parentheses for method

修饰符语句的右侧也是这些上下文之一 需要表达的地方。所以在a if b rescue c中,因为 b rescue c是一个语句,因此不允许作为 在if语句的条件下,代码必须解析为(a if b) rescue c

这与操作符优先级以下列方式交互:

 stmt if v = expr rescue x
 stmt if     expr rescue x
 stmt if v = expr unless x
 stmt if     expr unless x

解析为:

 stmt if v = (expr rescue x)
 (stmt if     expr) rescue x
 (stmt if v = expr) unless x
 (stmt if     expr) unless x