1.从hellowrold开始

 --语法和Python比较类似,直接像Python一样使用print即可
 --这里我可以直接写中文,显然被当成了注释。在lua中,两个-表示注释
 --[[
     这种形式可以表示多行注释
 ]]

 --在lua中,语句后面也可以像Python一样加分号,但也可以不加。
 print("hello world")

2.lua的基本类型

 --lua和Python一样,并不需要像C一样声明一个变量,因为本身带有值的类型
 --直接给变量赋值即可

 --[[
 lua的基本类型有:nil(空)
               boolean(布尔)
               number(数字)
               string(字符串)
               table(表)
               函数等内容后面再说

 ]]

 --[[
 注意:赋值的时候,可以将多个语句写在一行,用空格或者;分隔。
      这里只是演示,但是实际开发中不建议这么做
 ]]
 a = ;b="satori";c=3.14;d=math.pi
 --使用type查看值的类型
 print(type(a), type(b), type(c), type(d)) -- number    string    number    number
 --可以看到,lua中没有什么int float等等,只要是数字,类型通通为number
 print(type(print)) -- function

 --如果一个变量我们没有赋值直接使用的话,在Python中会报错,提示name xxx is not defined
 --但在lua中不会报错,对于一个没有赋值的变量在lua中默认为nil
 --nil用于区别其他变量,给一个全局变量赋值为nil等于删除这个全局变量
 print(mmp, type(mmp)) -- nil    nil

 --在lua中,只有false和nil表示假,其他的都表示真。0和空字符串在lua中表示真,这和Python不太一样

 --lua中,字符串一旦创建了,便不可以修改了。这和Python一样,但是在Python中可以使用replace修改并返回一个新的字符串
 --那么lua也有类似的方法,该方法同样会得到一个返回值,不会修改原来的值
 s1 = "hello cruel world"
 s2 = string.gsub(s1, "cruel", "beautiful")
 print(s1) -- hello cruel world
 print(s2) -- hello beautiful world

 --并且在lua中,可以使用单引号也可以使用双引号
 --类似于Python,如果输入的字符串本身有单引号,那么外部就用双引号,反之亦然
 print("I'm satori") --I'm satori
 --如果我非要使用相同的引号,那么可以使用转义字符,将内部的引号进行转义
 print('I\'m satori') --I'm satori

 --[[
     一些转义字符
     \a:响铃
     \b:退格
     \f:提供表格
     \n:换行
     \r:回车
     \t:制表  ]]
 print("i am \r satori, come from \n东方地灵殿")
 --[[
  satori, come from
 东方地灵殿   ]]

 --字符串也可以使用\加上三位数字表示,就是相应的ascii表
 print("\065")  --A

 -- 如果想表达多行字符串,可以使用[[ ]],类似于Python中的三引号'''  '''
 s3 = [[
     南村萝莉欺我老无力
   经常与我发生性
           关系
 ]]
 print(s3)
 --[[
     南村萝莉欺我老无力
   经常与我发生性
           关系
 ]]

 --如果一个字符串和一个数字进行运算的话,那么会尝试将字符串转化成数字
 --显然字符串必须是由数字组成,如果包含不是数字的字符,就会报错,无法转化
 ) 

 --字符串的连接,在lua中..表示字符串连接
 --不可以使用"a"+"b"这样的形式,这在Python中是允许的,但在lua中不可以。但可以使用..
 s4 = "  satori"
 print("a".."b"..s4) --ab  satori
 ") -- 1+1 == 2

 -- 如果我想获取一个字符串的长度该怎么办呢?在Python中使用len函数,但在lua中使用#。
 -- 而#在Python中表示注释,因此两门语言某些地方类似,某些地方又完全不同,确实很有意思

 -- 输出结果为45,咦,不是15吗?肯定一眼就找出答案了,一个汉字占三个字节
 -- 而且lua默认用的是utf-8编码。值得一提的是,在Python中使用len函数计算出来的结果为15
 -- 因为在Python中,len计算的是字符数,而不是字节数。
 -- 而且在go语言中,计算的结果也为45,同样是字节。如果想得到字符数,在go中需要用[]rune转化一下。
 s6 = "mmp"

 -- lua中还有一种叫做table的类型,说白了就是Python中的字典(哈希表),key和value一一对应
 hash_map = {}
 hash_map["satori"] = "东方地灵殿"
 print(hash_map["satori"]) -- 东方地灵殿
 -- 将hash_map赋值给别的变量,并且将hash_map删除
 hash_map_1 = hash_map
 hash_map = nil
 print(hash_map) -- nil
 print(hash_map_1["satori"]) -- 东方地灵殿
 -- 可以看到即使删除了hash_map,但不会对hash_map1造成影响
 -- lua的垃圾回收采用的是标记清除,当hash_map1也赋值为nil,没变量再引用的时候就会删除垃圾资源
 --如果访问一个不存在的key,那么得到的会是nil
 x = {}
 x[] =
 x[] =
 ], x[], x[])  -- 2    3    nil
 --想删除table中某个元素,直接赋值为nil即可
 x[] = nil
 ])  -- nil
 -- 而且table这种结构,还可以使用.来访问
 x.name = "satori"
 print(x.name)  -- satori

3.操作符

--1.算术操作符
a =
b = 

print(a/b) --7.5,这里和Python3一样,不是地板除,而是会包含小数部分
--这里值得注意的是,Python中平方是**,而lua中是^

--2.关系操作符
>) -- true
<) -- true
>=) -- true
<=) -- true
==) -- true
--注意:不等于在Python中是!=,但在lua中是~=
~=) -- true

--3.逻辑操作符, 这个和Python类似,有and,or,not
a1 =
a2 =   -- 别忘了0在lua中表示真,这和Python不一样
a3 = 

b1 =
b2 =
b3 = nil or false
--[[
对于a and b,首先and表示两边都为真整体才为真。如果a为真,那么还要判断b。a为假,b就不用判断了
因此对于 a and b,结果究竟是a还是b,其实不取决于b,而是取决于a。
如果a为真,那么由于and的特性,因此还要判断b,那么结果就为b,不管b是真还是假
如果a为假,那么由于and的特性,b不需要判断了,那么结果就为a

同理对于a or b也是一样。a or b表示两边都为假整体才为假
如果a为真,那么不管b是真是假,整体都为真,所以b无需判断,结果就为a
如果a为假,那么还要判断b,因此结果就是b。

因此在lua和其他语言一样,也存在着短路求值,当第一个条件已经能够决定整体的结果时,剩下的条件就不会再判断了

举一个C语言的例子
#include <stdio.h>
int main()
{
    int a = 10;
    if (1<0 && a++)
    {
        printf("你猜a的值为多少?\n");
    }
    printf("a=%d\n", a);

    if (1<0 || a++)
    {
        printf("你猜a的值又为多少\n");
    }
    printf("a=%d\n", a);
}
第一次打印a的时候,值为10,因为1<0为false,所以a++无序判断,因此a++根本没有执行。
第二次打印a的时候,值为11,因此1<0为false,但是操作符是or,所以会判断a++,因此if语句执行完之后打印11
]]
print(a1, a2, a3) --5    4    nil
print(b1, b2, b3) --5    7    false

-- 那么对于4 and 5 and nil or 4 and 5 or 7,会打印什么结果
--[[
操作符从左往右看,4 and 5结果为5,5再and nil,结果为nil, nil 再or 4,结果为4, 4 and 5结果为5, 5 or 7结果为5
]]
    )
--[[
    我们也可以用这种方式来模拟三元操作符
    v = a or b,如果a为真,v=a,否则等于b
    v = a>b and x or y,如果a>b,结果为x。因为a>b为真,(a>b and x) == x, x又为真,那么or上y当然为x
                       如果a<b,结果为y。因此a<b,那么a>b为假,(a<b and x)==(a<b),一个假or上y当然为y
        因此 v = a>b and x or y,就类似于C中v = a>b?x:y,类似于Python中v = x if a>b else y
]]

-- not就比较简单了,表示取反
print(not false) --true
) --false
print(not nil) -- true
print(not "satori") --false

--4.字符串的连接
--前面介绍过可以使用..连接字符串
print("宇宙には始まりはあるが".."、終わりはない".."、無限") --宇宙には始まりはあるが、終わりはない、無限
print("星にもまた始まりはあるが".."自らの力を持って滅び逝く".."有限") --星にもまた始まりはあるが自らの力を持って滅び逝く有限
-- 如果字符串和数字拼接,那么会自动将数字转化成字符串
a =
print("96猫@"..a.."cm")  --96猫@142cm
--[[
    这里需要注意的是,我们是用a表示142,也可以直接写上142
    print("96猫"..142),也是合法的,但是,我要说但是了。
    如果直接写上142的话,那么后面就不能再接..了,意思就是"96猫"..142是合法的,会得到96猫142,但是142.."96猫"是非法的。
    如果将这个值赋值给一个变量,a = 142,那么"96猫"..a,和a.."96猫"都是合法的
]]

--5.操作符优先级
--[[
这个就不介绍了,跟其他语言类似。
总之一句话:如果不确定的话,那么使用括号就可以了
]]

--6.table构造式
days = {"星期一", "星期二", "星期三","星期四","星期五","星期六","星期日"}
--table每一个元素是由key和value组成的,而我们这里显然不是键值对的形式
--在lua中,在不指定key的情况下,可以使用索引来指定。但是比较恶心的是,索引默认是从1开始的,这个比较反人类。
--所以days[1]便是第一个元素,days[2]是第二个元素。感觉table既有点像数组也有点像字典
]) --星期一
]) --星期四
]) --星期日
--table还有一种构造形式
days = {name=, anime="东方地灵殿"}
--等价于:days={}; days.name="satori"; days.age=18; days.anime="东方地灵殿"
print(days.name, days.age, days["anime"]) --satori    18    东方地灵殿
--不管怎么创建,lua中的table和Python的dict一样,都可以自由动态的添加或者删除。
--添加:直接写上key value即可,删除:直接令相应key对应的value等于nil即可

4.语句

 --1.赋值

 --首先lua和Python一样,可以进行多重赋值
 a,b=,
 print(a,b) --1    2

 --也可以直接进行两数交换,而不需要中间变量
 a,b=b,a
 print(a,b) --2    1

 --比较特殊的一点,当左边的变量和右边的值在数量上不匹配的时候
 x,y,z = , --这句代码在Python中毫无疑问会报错,但在lua中不会
 --当左边的变量数多于右边的值的时候,那么得不到值得变量会被赋值为nil
 print(x,y,z) --1    2    nil
 x,y = ,, --同样这句代码在Python中也会报错,但在lua中也不会
 --当左边的变量数少于右边的值的时候,多余的值会被自动丢弃
 print(x,y) --1    2
 --但是值最好要匹配

 --2.局部变量和块

 --局部变量,声明一个局部变量只需要在变量前面加上local关键字即可,局部变量只在当前的语句块里面有用
 --如果不加local,在while循环中新建一个y,那么while循环结束后,打印y,会打印循环里面给y赋的值。
 --因为循环里面的y是全局的,会覆盖上面的y
 x =
 y =
  do
     y =
     x = x+
 end

 --但是当我加上了local,会发现打印的还是40,因为局部变量不会对全局变量造成影响
 --类似于Python中的函数,在函数中定义的变量,只要不加global关键字,都是局部变量
 --并且Python无法在while循环中声明一个局部变量。循环,条件语句等等,对于Python来说,只有全局变量。但lua可以。
 x =
 y =
  do

     x = x+
 end

 var1 =
 var2 =
 > then

     var2 =
 end

 --可以看到var1没被修改,var2被修改了。if里面的var1只在if里面有效,不会对外面的var1造成影响。而var2是会覆盖外面的var2的。

 xxx =
  then

     print(xxx)
 else

 end
 --如果if条件成立,会打印666,但是不成立,会打印123.

 --但是如果我没在条件语句、循环等等中声明局部变量,而是在最外面声明一个局部变量呢?

 > then
     v =
 end

 --会发现这个局部变量,就等同于全局变量
 --此外,我们还可以使用do end来声明一个语句块。当遇到lua解释器遇到do,会先找到对应的end,然后执行do和end里面的内容。
 do

 end
 print(wanwan) -- nil
 --由于我声明了do end,那么do end里面的局部变量是无法在外面被检测到的,所以打印为nil。
 --值得一提的是,如果不加local,那么wanwan仍旧是一个全局变量,在外面还是可以访问的到的。
 --局部变量会虽着作用域的结束而消失

 --3.控制结构
 --if条件语句,和Python比较类似。但是需要在条件语句结束后加上end,有点像Python的tornado框架里的模板语言。
 --此外if条件后面还需要加上then
 if false then
     print("古明地觉")
 >= then
     print("芙兰朵露斯卡雷特")--芙兰朵露斯卡雷特
 else
     ")
 end
 --此外,if语句还可以嵌套
 gender = 'f'
 age =
 if gender == 'f' then
      then
         print("获取我们可以做一场交易")
      then
         print("虽然担些风险,但也值得一试")-- 虽然担些风险,但也值得一试
     else
         print("最低三年,最高死刑")
     end
 else
     print("oh♂yeah SIR")
 end
 --此外,连接两个条件,lua中也使用and or关键字,而不是&&和||

 --循环语句
 x =
  do
     print(x)
     x = x +  --注意不可以写成x+=1的形式
     --[[
     10
     11
     12
     13
     14 ]]
 end
 -- 可以想象相较于Python,把:换成了do,并且在结尾加上了end

 --并且在lua中还有一个repeat until,表示啥呢?从名字也能看出,重复····直到···
 --不得不说,往往英语不是母语的人,发明出来的语言,关键字更清晰易懂。
 x =
 repeat
     x = x+
     print(x)
     --[[
         2
         3
         4 ]]

 --这段代码表示啥呢?不断地重复x = x+1; print(x),直到x>3为止,你再往下走

 --当然lua中还有for循环
 --[[
 结构:
 for i=a,b,c do
     <body>
 end
 这几行代码是什么意思呢?转化为while循环
 i=a
 while i<=b do
     <body>
     i = i+c
 end
 注意:如果c不指定,默认为1
 ]]
 ,, do
     print(i)
 end
 --[[
 1
 4
 7
 10 ]]
 --注意:for循环里面的i,只在for里面有效。for循环结束后,就被自动销毁了。
 print(i) --nil

 --for遍历table
 t = {name=, gender="f"}
 --和Python不一样,在lua中不能直接遍历,需要遍历pairs(table),可以只遍历key,也可以遍历key和value
 for k,v in pairs(t) do
     print(k,v)
     --[[
         gender  f
         name    satori
         age     18 ]]
 end

 --如果遍历的时候,同时指定索引
 --此时的t就类似于数组,可以直接使用索引访问,但是从1开始,反人类
 t = {"satori", "koishi","mashiro"}
 ]) --satori
 for k,v in ipairs(t) do
     print(k, v)
 end
 --[[
 1    satori
 2    koishi
 3    mashiro  ]]

 --查找某个值所在的位置
 days = {"星期一","星期二","星期三","星期四","星期五","星期六","星期日"}
 for k,v in ipairs(days) do
     if v == "星期三" then

     end
 end

 --4.break和return
 --break,跳出所在的循环, 如果外部还有循环则不会跳出。
 --return,只能出现在函数里,结束函数并返回一个值
 , do
      then
         break
     end
     print(i)
     --[[
         1
         2  ]]
 end
 --return等介绍函数的时候再说

5.函数

 --如何定义一个函数
 --[[
 函数结构:
 function foo()
     <body>
 end
 ]]
 function add(a)
     b =
     print(a+b)
 end
 add()
 print(b) --11,这里打印11,说明能找到add函数里面的b,明明是在函数里面,函数结束了,居然没有被销毁。
 --显然不加local,即使是在函数里,外部也能访问的到。
 --像os.date(),math.sin()等等都属于函数
 print(os.date()) --10/18/18 14:16:38
 )) --0.5

 --函数的传参
 function foo(a,b)
     print(a,b)
 end
 --这里foo函数需要指定两个参数,但如果我只指定一个会怎么样?指定三个又会怎么样
 foo() --666    nil
 --可见没有得到值的参数会等于nil
 foo(,,) --666    777
 --多余的值会自动丢弃,这在Python中是不允许的,该传几个就传几个
 --类似于赋值a,b=1 ; x,y=1,2,3

 --另一种传参方式
 function foo(...)
     local a,b,c=...
     print(a,b,c)
 end
 foo(,,) -- 1    2    3

 --函数的返回值,这个和Python一样,可以返回多个,比如string.find()函数
 print(string.find("hello cruel world", "cruel")) -- 7    11
 --这里有两个返回值,7表示cruel的开始位置,11表示cruel的结尾位置。当然索引是从1开始的,反人类。

 --自己定义一个函数,接受一个数组,返回数组的最大值以及索引
 function get_max_value(arr)
     max = arr[]
     ind =
     for index, value in ipairs(arr) do
         if value > max then
             max,ind = value,index
         end
     end
     return max,ind
 end
 ,,,,,,,,,})) --42423        8, 索引从1开始,反人类

 --首先函数即变量,函数也是可以直接赋值的
 t = {a=print}
 t.a("hello world") --hello world

 math.sin, print = print, math.sin
 )) --0.5
 --可以看到进行交换之后,可以直接当做对方去使用。
 --这里我们在交换回来,不然下面不好进行了
 math.sin, print = print, math.sin

 function foo()
     return "古明地觉"
 end
 bar = foo
 print(bar()) --古明地觉

 --匿名函数,其实说白了还是普通的函数,只是可以写在一行,并且省了函数名
 --类似Python里的lambda,只建议定义一些简单的逻辑。
 foo =  end
 )) --4,

 --使用function还可以对table里面的元素进行排序
 --table.sort函数可以对一个table进行排序
 girls = {
     {name=},
     {name=},
     {name=},
 }
 --这个函数会直接在原table上进行修改
 table.sort(girls, function(a,b) return (a.name>b.name) end)
 for i,v in ipairs(girls) do
     print(v.name)
     --[[
         satori
         mashiro
         koishi  ]]
 end
 --[[
 可以看到按照name从大到小排列了,a,b就代表了table里面的所有元素。每两个进行比较,a.name大的放在前面。
 再比如Python:
 girls = [
     {"name":"satori", "age":18},
     {"name":"koishi", "age":17},
     {"name":"mashiro", "age":16}
 ]
 girls.sort(key=lambda x: x["name"])
 这个x就代表了girls里面的每一个元素,怎么排,按照x["name"]来排,这个默认是从小到大排
 ]]

 --关于排序,还可以按照table去排序其他table,怎么理解呢?
 girls = {"mashiro", "satori", "koishi"}
 age = {mashiro=, satori=, koishi=}
 --此时girls和age一一对应,我想age从小到大的方式排序girls
 table.sort(girls, function (a,b) return age[a]<age[b] end)
 ], girls[], girls[]) --mashiro    koishi    satori

 --计算导数
 --导数公式,(f(x+d) - f(x)) / d ,这个d趋近于无穷小
 function derivative(f, delta)
     delta = delta or 1e-4 --这算是缺省参数,如果我们不指定,那么delta为nil和1e-4进行or运算,会等于1e-4
     return function(x)
         return (f(x+delta) - f(x)) / delta
     end
 end
 --这里使用了闭包,闭包就是函数内部还嵌套一个函数,并且内部嵌套的函数,要引用外部函数的变量
 foo = derivative(math.sin, 1e-5)
 )) -- -0.83906880893325, 便是函数math.sin在x=10处的导数

 function newCounter()

     return function()
         i = i+
         print(i)
     end
 end
 --内部的i是可以访问到外部的i的
 f = newCounter() --此时的f就是闭包里面的那个函数
 --显然这个i并没有被销毁,因为在外部有f指向内部的函数,因此没调用一次,i就会加1,这和go语言基本上一样
 --和Python也有点相似,只不过Python中需要nonlocal关键字声明
 f()
 f()
 f()
 --函数递归,最经典的便是阶乘
 function fac(x)
      then

     end
     )
 end
 ))
 ********) 

(一)lua基础语法的更多相关文章

  1. Lua基础语法讲解

    Lua 是什么? Lua 是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能. Lua 是巴西里约热内卢天主教大学( ...

  2. Lua - 基础语法

    Hello World 交互式编程 Lua 交互式编程模式可以通过命令 lua -i 或 lua 来启用: [huey@huey-K42JE lua]$ lua Lua 5.1.4 Copyright ...

  3. lua——基础语法

    -- test lua: for learning lua grammar -- line comment --[[ block comment ]]-- -- print hello world p ...

  4. Nginx详解二十二:Nginx深度学习篇之Lua解释器安装及基础语法

    解释器 Lua:Lua是一个简洁.轻量.可扩展的脚本语言 Nginx+Lua优势充分的结合Nginx的并发处理epoll优势的Lua的轻量实现简单的功能切高并发的场景 安装Lua 1.安装解释器:yu ...

  5. 大体了解Lua的语法

    Lua 的语法比较简单,学习起来也比较省力,但功能却并不弱. 在Lua中,一切都是变量,除了关键字.请记住这句话. I. 首先是注释 写一个程序,总是少不了注释的. 在Lua中,你可以使用单行注释和多 ...

  6. Lua基础 函数(一)

    转自: http://blog.csdn.net/wzzfeitian/article/details/8653101 在Lua中,函数是对语句和表达式进行抽象的主要方法.既可以用来处理一些特殊的工作 ...

  7. Python学习的个人笔记(基础语法)

    Python学习的个人笔记 题外话: 我是一个大二的计算机系的学生,这份python学习个人笔记是趁寒假这一周在慕课网,w3cschool,还有借鉴了一些博客,资料整理出来的,用于自己方便的时候查阅, ...

  8. python基础语法及知识点总结

    本文转载于星过无痕的博客http://www.cnblogs.com/linxiangpeng/p/6403991.html 在此表达对原创作者的感激之情,多谢星过无痕的分享!谢谢! Python学习 ...

  9. Cocos2d-x 脚本语言Lua基本语法

    Cocos2d-x 脚本语言Lua基本语法 前面一篇博客对Lua这门小巧的语言进行了简单的介绍.本篇博客来给大家略微讲一下Lua的语法.不会长篇累牍得把Lua的全部语法都讲一遍,这里通过下面几点来讲L ...

随机推荐

  1. 【解决】Node JS Error: ENOENT

    The Node Beginner Book 书中的实例代码当上传图片时会报Error: ENOENT, 原因:图片默认会选择系统的缓存文件夹下,在windows下无权访问C盘,所以就报错了.. 解决 ...

  2. Linux nohup 后台运行命令

    有一些爬虫的程序需要在后台运行,所以简单总结了一下nohup 的一些用法 基本命令:nohup command  $; 运行之后出现nohup: ignoring input and appendin ...

  3. 关于C标准

    关于C标准 1. 前言 本文从英文 C-FAQ (2004 年 7 月 3 日修订版) 翻译而来.本文的 中文版权为朱群英和孙云所有. 本文的内容可以自由用于个人目的,但 是不可以未经许可出版发行. ...

  4. maven中如何得到父工程的位置

    目前的项目是一个父子工程项目,想要在子工程的pom文件中操作父工程目录下的资源. maven官方提供了标准的写法,比如parent.basedir之类的,网上可以找到很多,但尝试了之后就是不识别. 搞 ...

  5. float与定位的区别

    float和绝对定位的区别 CSS中脱离文档流,也就是将元素从普通的布局排版中拿走,其他盒子在定位的时候,会当做脱离文档流的元素不存在而进行定位.1 需要注意的是,使用float脱离文档流时,其他盒子 ...

  6. [POI2011]Lightning Conductor

    题面在这里 description 已知一个长度为\(n\)的序列\(a_1,a_2,...,a_n\). 对于每个\(1\le i\le n\),找到最小的非负整数\(p\), 满足对于任意的\(1 ...

  7. 【luogu 1439 最长公共子序列】

    题目描述 给出1-n的两个排列P1和P2,求它们的最长公共子序列. 输入输出格式 输入格式: 第一行是一个数n, 接下来两行,每行为n个数,为自然数1-n的一个排列. 输出格式: 一个数,即最长公共子 ...

  8. JS获取当前时间及时间戳相互转换

    1.获取当前时间的 时间戳 Date.parse(new Date()) 结果:1486347562000 2.获取当前 时间 new Date() 结果:Mon Feb 06 2017 10:19: ...

  9. git使用笔记(九)操作原理

    By francis_hao    Nov 27,2016   参考[1]的一张图已经把git的基本原理描述的很清楚了,如下:   下面以实例演示其过程,需要用到两个命令cat-file和ls-fil ...

  10. [poj 3252]数位dp前导0的处理

    通过这个题对于数位dp中前导0的处理有了新的认识. 题目链接:http://poj.org/problem?id=3252 //http://poj.org/problem?id=3252 #incl ...