目录

Lua初探-Expressions上


Expressions
  • 一下为Lua中基本的表达式

      exp ::= prefixexp
      exp ::= nil | false | true
      exp ::= Numeral
      exp ::= LiteralString
      exp ::= functiondef
      exp ::= tableconstructor
      exp ::= ‘...’
      exp ::= exp binop exp
      exp ::= unop exp
      prefixexp ::= var | functioncall | ‘(’ exp ‘)’
    
  • 以下为一些示例:

       f()                -- adjusted to 0 results
       g(f(), x)          -- f() is adjusted to 1 result
       g(x, f())          -- g gets x plus all results from f()
       a,b,c = f(), x     -- f() is adjusted to 1 result (c gets nil)
       a,b = ...          -- a gets the first vararg argument, b gets
                          -- the second (both a and b can get nil if there
                          -- is no corresponding vararg argument)
    
       a,b,c = x, f()     -- f() is adjusted to 2 results
       a,b,c = f()        -- f() is adjusted to 3 results
       return f()         -- returns all results from f()
       return ...         -- returns all received vararg arguments
       return x,y,f()     -- returns x, y, and all results from f()
       {f()}              -- creates a list with all results from f()
       {...}              -- creates a list with all vararg arguments
       {f(), nil}         -- f() is adjusted to 1 result
    
  • 括在括号中的任何表达式始终只生成一个值。因此,(f(x,y,z))总是单个值,即使f返回多个值。 (如果f不返回任何值,则(f(x,y,z))的值是f或nil返回的第一个值。)


一、算术操作
  • Lua支持如下算术操作

    • +: addition 加
    • -: subtraction 减
    • *: multiplication 乘
    • /: float division 除
    • //: floor division
    • %: modulo 取模
    • ^: exponentiation 幕
    • -: unary minus 取反
  • 算术操作的详细解析前面章节已有说明,这里不再累赘。


二、位操作
  • Lua支持如下位操作
    • &: bitwise AND
    • |: bitwise OR
    • ~: bitwise exclusive OR
    • : right shift

    • «: left shift
    • ~: unary bitwise NOT

三、Coercions and Conversions 强制转换与转换
  • Lua在运行期间提供了一些类型和表达式的自动转换。
    • 1、Float类型的操作数在进行位操作时,Lua总是将其转换为整型进后再操作。
    • 2、幕操作和/ float division操作时如果操作数为整型,总是会将整型的操作数转换为浮点型。
    • 3、应用于混合数字(整数和浮点数)的所有其他算术运算将整数操作数转换为浮点数。
    • 4、只要预期数字,Lua也会将字符串转换为数字。
    • 5、在从整数到浮点数的转换中,如果整数值具有精确的表示形式,则为结果。否则,转换得到最接近的较高或最接近的较低可表示值。这种转换永远不会失败。
    • 6、从float到integer的转换检查float是否具有整数的精确表示(即,float具有整数值,并且它在整数表示的范围内)。 如果是,则表示结果。 否则,转换失败。
    • 7、从字符串到数字的转换如下:首先,按照语法和Lua词法分析器的规则将字符串转换为整数或浮点数。 (该字符串可能还有前导和尾随空格以及符号。)然后,结果数(浮点数或整数)将转换为上下文所需的类型(浮点数或整数)(例如,强制转换的操作)。
    • 8、从字符串到数字的所有转换都接受点和当前区域设置标记作为基数字符。 (然而,Lua lexer只接受一个点。)
    • 9、从数字到字符串的转换使用未指定的人类可读格式。要完全控制数字如何转换为字符串,请使用字符串库中的format函数

四、Relational Operators 关系运算
  • Lua支持如下的关系运算

    • ==: equality
    • ~=: inequality
    • <: less than
    • : greater than

    • <=: less or equal
    • =: greater or equal

  • 运算符的操作结果总是false或者true

  • 等于(==)首先比较其操作数的类型。 如果类型不同,则结果为false。 否则,比较操作数的值。 字符串以明显的方式进行比较。 如果它们表示相同的数学值,则数字相等

  • 通过表 table,userdata和线程threads的比较是通过引用进行比较:只有当两个对象是同一个对象时才认为它们是相等的。 每次创建新对象(表,用户数据或线程)时,此新对象都不同于以前存在的任何对象。 封闭总是等于它自己。 具有任何可检测差异(不同行为,不同定义)的闭包总是不同的。 在不同时间创建但没有可检测到的差异的闭包可以被分类为相同或不同(取决于内部缓存细节)。

  • 你可以通过使用eq元方法去改变Lua中tables和userdata的比较方式。


五、Logical Operators 逻辑操作
  • 在Lua中的逻辑操作有and、or、not。

  • 如下为一些示例

       10 or 20            --> 10
       10 or error()       --> 10
       nil or "a"          --> "a"
       nil and 10          --> nil
       false and error()   --> false
       false and nil       --> false
       false or nil        --> nil
       10 and 20           --> 20
    

六、Concatenation 级联操作
  • ua中的字符串连接运算符由两个点(’..’)表示。如果两个操作数都是字符串或数字,则它们将根据Lua的级联规则转换为字符串。否则,调用__concat元方法

七、The length Operator 长度操作
  • 长度操作由一元前缀运算符#完成。

  • 字符串的长度是其字节数(即,每个字符为一个字节时字符串长度的通常含义)。

  • 应用于表的长度运算符返回该表中的边框。表t中的边界是满足以下条件的任何自然数:

     (border == 0 or t[border] ~= nil) and t[border + 1] == nil
    
  • 换句话说,边框是表中的任何(自然)索引,其中非零值后跟零值(或者当索引1为零时为零)

  • 只有一个边框的表称为序列。 例如,表{10,20,30,40,50}是一个序列,因为它只有一个边界(5)。 表{10,20,30,零,50}具有两个边界(3和5),因此它不是序列。 表{nil,20,30,nil,nil,60,nil}有三个边框(0,3和6),所以它也不是一个序列。 表{}是带边框0的序列。请注意,非自然键不会干扰表是否为序列。

  • 当t是序列时,#t返回其唯一的边界,这对应于序列长度的直观概念。 当t不是序列时,#t可以返回其任何边界。 (确切的一个取决于表的内部表示的细节,而这又取决于表的填充方式和非数字键的内存地址。)

  • 表的长度的计算具有保证的最差时间O(log n),其中n是表中最大的自然键。

  • 程序可以通过__len元方法修改长度运算符对任何值的行为,除了字符串