Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/lua/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
关于lua corountine的困惑';s恢复与屈服函数_Lua_Coroutine - Fatal编程技术网

关于lua corountine的困惑';s恢复与屈服函数

关于lua corountine的困惑';s恢复与屈服函数,lua,coroutine,Lua,Coroutine,我通过这个学习lua,它有一段代码: co = coroutine.create(function() for i=1,5 do print(coroutine.yield(i)) end end) print(coroutine.resume(co,1,2)) print(coroutine.resume(co,3,4)) print(coroutine.resume(co,5,6)) print(coroutine.resume(co,7,8)) print

我通过这个学习lua,它有一段代码:

co = coroutine.create(function()
    for i=1,5 do
      print(coroutine.yield(i))
    end
  end)

print(coroutine.resume(co,1,2))
print(coroutine.resume(co,3,4))
print(coroutine.resume(co,5,6))
print(coroutine.resume(co,7,8))
print(coroutine.resume(co,9,10))
print(coroutine.resume(co,11,12))
输出如下:

true    1
3   4
true    2
5   6
true    3
7   8
true    4
9   10
true    5
11  12
true

但我不明白yield和resume是如何相互传递参数的,为什么yield不输出resume传递给它的第一个1,2,有人能解释一下吗?谢谢正常的Lua函数有一个入口(传入参数)和一个出口(传出返回值):

通过将参数放在括号内,将参数名(局部变量)绑定到参数名上,可以通过将函数调用表达式放在赋值语句的右侧或较大表达式(例如,另一个函数调用)内来检索作为
return
语句一部分列出的返回值

调用函数还有其他方法。例如,
pcall()。通过将参数作为参数放入
pcall()
函数调用(函数本身之后)来传递参数
pcall()
还预加一个额外的返回值,该值指示函数是正常退出还是通过错误退出。被调用函数的内部是不变的

print( "f returned", pcall( f, 1, 2 ) )
--> arguments       1       2
--> f returned      true    I'm     done
您可以使用
coroutine.resume()
而不是
pcall()
来调用协同程序的主函数。参数的传递方式和额外的返回值保持不变:

local th = coroutine.create( f )
print( "f returns", coroutine.resume( th, 1, 2 ) )
--> arguments       1       2
--> f returns       true    I'm     done
但是使用协同路由,您可以(暂时)退出函数:
coroutine.yield()
。通过将值作为参数放入
yield()
函数调用中,可以通过
coroutine.yield()
传递值。这些值可以作为
coroutine.resume()
调用的返回值而不是正常的返回值在外部检索

但是,您可以通过再次调用
coroutine.resume()
重新输入生成的协同路由。协同路由在其停止的位置继续,传递给
coroutine.resume()
的额外值可作为之前挂起协同路由的
yield()
函数调用的返回值

local function g( a, b )
  print( "arguments", a, b )
  local c, d = coroutine.yield( "a" )
  print( "yield returned", c, d )
  return "I'm", "done"
end

local th = coroutine.create( g )
print( "g yielded", coroutine.resume( th, 1, 2 ) )
print( "g returned", coroutine.resume( th, 3, 4 ) )
--> arguments       1       2
--> g yielded       true    a
--> yield returned  3       4
--> g returned      true    I'm     done
请注意,产量不需要直接位于协同程序的主函数中,它可以位于嵌套函数调用中。执行跳回
coroutine.resume()
,它首先(重新)启动了coroutine

现在问一下为什么第一个
resume()
中的
1,2
没有出现在输出中:您的coroutine main函数没有列出任何参数,因此会忽略传递给它的所有参数(在第一个函数条目上)。类似地,由于main函数不返回任何返回值,因此最后一个
resume()
除了指示成功执行的
true
之外,不会返回任何额外的返回值

co = coroutine.create(function()
    for i=1,5 do
      print(coroutine.yield(i))
    end
  end)
我们第一次启动协同程序时使用:

print(coroutine.resume(co,1,2))
它将一直运行到第一个产量。我们的第一个resume调用将返回true和yield参数(这里i=1),这解释了第一个输出行

我们的合作现在暂停。一旦我们再次呼叫resume:

print(coroutine.resume(co,3,4))
你的第一份简历最终会返回,你当前简历的参数(3,4)将被打印出来。第二次迭代开始时,调用coroutine.yield(2),这将再次使您的上一份简历返回true,依此类推


因此,实际上在您的示例中,coroutine.resume(co)对于第一次调用就足够了,因为任何进一步的参数都会丢失。

我们看到这种行为的原因很微妙,但它与“进入”和“退出”语句的不匹配有关。它还与匿名函数中调用
print
yield
的顺序有关

让我们想象一下
print(coroutine.yield(i))
vs.迭代的执行图

在第一次迭代中,我们有
coroutine.resume
pass
1
2
到coroutine。这是原点,因此我们不是从以前的
,而是匿名函数本身的原始调用。在打印内部调用
yield
,返回
i=1
,但不调用
print
。函数退出

接下来是在我们看到下一个
coroutine.resume
恢复之前,函数暂停一段时间。此
resume
通过
3
4
。函数在最后一次
生成时拾取
。请记住,
print
函数未被调用,因为第一个
yield
首先被调用并退出程序?执行在
print
中返回,因此现在调用
print
,但这次返回
3
4
,因为这是要传递的最新值。该函数再次重复,在
print
之前调用
yield
,返回
i=2

如果我们继续迭代,我们将更明确地了解为什么我们没有看到
1
2
的基本模式。我们的第一次迭代是“退出”收益率与相应的“进入收益率”不成对。这对应于第一次执行协程
co

我们可能期望最后一个
收益率
也不成对,但不同的是,我们将有一个“进入”
收益率
,它是不成对的,而不是一个“退出”
收益率
,它是不成对的。这是因为循环已经完成。这解释了为什么我们看到
11 12
后面跟着
true
,后面没有“退出”
yield
return

这种情况与内部for循环的奇偶性(偶数/奇数)无关。唯一重要的是
简历<
print(coroutine.resume(co,3,4))