让你真正理解 lua 泛型for

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/HQ354974212/article/details/89381527

最近在看lua,看到泛型for一脸懵逼,完全不知道究竟是怎么运转的,今天拿一个常见的例子来跟大家讲个透彻!!!

泛型 for 的执行过程:

(1) in  后面表达式应返回:迭代函数、状态常量、控制变量; 如果表达式返回的结果个数不足三个会自动用 nil 补足,超出三个的会被忽略。

(2)  迭代函数 传入两个参数 状态常量、控制变量 ,迭代函数的第一个返回值 如果为nil ,则停止循环 ; 否则第一个返回值 赋值给  控制变量  ,再次循环调用迭代函数

function square(N,j)
    if j<N
    then
        j = j+1
        return j, j*j
    end
end


--         迭代函数、状态常量、控制变量  
for i,v in  square,   3,       0
do
    print(i,v)
end

打印结果:

按照执行规则,我们来分析一下上述代码:

(1) in  后面表达式应返回:迭代函数 square、状态常量 3、控制变量 0;  

(2)  迭代函数square 传入两个参数 状态常量 3、控制变量0 ,   

第一次调用迭代函数返回1 ,  1*1   (两个值分别赋值给i,v,第一个返回值1 不为nil ,则将第一个返回值 赋值给  控制变量(0变为1)  

再次循环调用迭代函数,状态常量 3、控制变量1 , 迭代函数返回2 ,  2*2   (两个值分别赋值给i,v,第一个返回值2 不为nil ,则将第一个返回值 赋值给  控制变量(1变为2)  

再次循环调用迭代函数,状态常量 3、控制变量2 , 迭代函数返回3 ,  3*3   (两个值分别赋值给i,v,第一个返回值3 不为nil ,则将第一个返回值 赋值给  控制变量(2变为3) 

再次循环调用迭代函数,状态常量 3、控制变量3 , 迭代函数不返回,则为nil  (两个值分别赋值给i,v,第一个返回值nil,停止循环。


for    V1, ... ,Vn    in    表达式 

do

  语句...

end

-- 就等价于以下代码:


local   _f  , _c  ,  _i =  表达式返回的  迭代器函数、恒定状态、控制变量的初值
     while  true do 
          local  R1, ..., Rn = _f(_c, _i)
          _i= R1
          if  R1 == nil  then break end
            语句
          end
end


了解了上面的原理,我们来看下面的简写例子就容易理解了

--迭代器工厂函数
function iterCreater(a)
    local i= 1

    --返回一个closure用来保存 i 的值
    return

    function( )
        e =a[i]
        i=i+1
        return e
    end
end


t={ 1,2,3,4,5 }


for  r  in iterCreater(t) do
    print(r)
end

按照执行规则,我们来分析一下上述代码:

(1) in  后面表达式返回(只有一个返回值,所以后面两个为nil):迭代函数 (无名称)、 状态常量 nil、控制变量初值 nil;  

(2)  迭代函数 (无名称)  ,这个函数无需参数,   

第一次调用 迭代函数 i=1,返回1   (赋值给r,第一个返回值1 不为nil ,则将第一个返回值 赋值给  控制变量(nil变为1)  

再次循环调用迭代函数,状态常量 nil、控制变量1 ,  i=2,迭代函数返回2   (赋值给r,第一个返回值2 不为nil ,则将第一个返回值 赋值给  控制变量(1变为2)  

再次循环调用迭代函数,状态常量 nil、控制变量2 ,  i=3,迭代函数返回3  (赋值给r,第一个返回值3 不为nil ,则将第一个返回值 赋值给  控制变量(2变为3) 

...

再次循环调用迭代函数,状态常量 nil、控制变量6 ,i=6,迭代函数返回nil (赋值给r, 第一个返回值nil,停止循环。

例子中因为不需要状态常量,所以 表达式只返回了  迭代函数 状态常量 、控制变量初值  就默认为nil了


我们将上面的例子改造下,表达式也按规则返回三个值(后面的111,222其实没什么用,只是为了打印印证规则)

--迭代器共厂函数
function iterCreater(a)
    local i= 1

    --返回一个closure用来保存 i 的值
    return

    function( x,y)
        print("x:".. x , "y:"..y)
        e =a[i]
        i=i+1
        return e
    end ,111,222
end


t={ 1,2,3,4,5 }


for  r  in iterCreater(t) do
    print(r)
end

打印结果

按照执行规则,我们来分析一下上述代码:

(1) in  后面表达式返回三个值:迭代函数 (无名称)、 状态常量 111、控制变量初值 222;  

(2)  迭代函数 (无名称)  传入两个参数  状态常量 111、控制变量初值 222,   

第一次调用 迭代函数 ,迭代函数打印111, 222 ), i=1 ,返回1   (赋值给r,第一个返回值1 不为nil ,则将第一个返回值 赋值给  控制变量(222变为1)  

再次循环调用迭代函数,状态常量 111、控制变量1 , (迭代函数打印111, 1 ), i=2, 迭代函数返回2   (赋值给r,第一个返回值2 不为nil ,则将第一个返回值 赋值给  控制变量(1变为2)  

再次循环调用迭代函数,状态常量111、控制变量2 ,  (迭代函数打印111, 2 ), i=3,迭代函数返回3  (赋值给r,第一个返回值3 不为nil ,则将第一个返回值 赋值给  控制变量(2变为3) 

...

再次循环调用迭代函数,状态常量 111、控制变量5 , (迭代函数打印111,5 ), i=6, 迭代函数返回nil (赋值给r, 第一个返回值nil,停止循环。

猜你喜欢

转载自blog.csdn.net/HQ354974212/article/details/89381527
今日推荐