tcl - 如何检测 Tcl 协程的完成?
问题描述
我想在 Tcl 中找到一种检测协程结束的好方法。考虑:
coroutine cor apply {{} {
yield 1
yield 2
yield 3
}}
try {
puts [cor]
puts [cor]
puts [cor]
puts [cor]
} trap {TCL LOOKUP COMMAND cor} {e} {
puts "done"
}
这行得通,但感觉就像一个黑客,而且很脆弱。如果我重命名cor
并忘记在陷阱中重命名它,它将失败。如果我cor
在陷阱中省略了,它将捕获不相关的拼写错误。
一定有更好的方法。它是什么?
解决方案
要检测命令是否仍然存在,请使用info commands
并检查它返回的列表的长度。(我假设您可以保证命令名称中没有 glob 字符;如果这是真的,那么检查非常便宜。)
while {[llength [info commands cor]]} {
puts [cor]
}
但是,如果您打算将协程用作生成器并且仅在循环中使用,则可以让它直接发出信号表明它已完成。为此,让它产生一个break
.
coroutine cor apply {{} {
yield [info coroutine]; # A sensible result from [coroutine]
yield 1
yield 2
yield 3
return -code break
# [tailcall break] would also work
}}
while true {
puts [cor]
}
诀窍是你不要 yield
休息;您将其用作协程的最终结果。(您的旧协程正在使用yield
as that 的结果,可能主要是靠运气。)
在写这篇文章时,我注意到了一个错误。运行协程的循环在 8.6.8(我检查过的唯一版本)的顶层不起作用。不知道为什么。在过程/apply
上下文中很好(将协程名称作为参数传递是很自然的):
apply {c {
while true {
puts [$c]
}
}} cor
这些不同运行方式的字节码看起来并没有明显的不同。强制解释也会使事情正常进行,这很好地表明这是一个真正的错误。
set while while
$while true {
puts [cor]
}
推荐阅读
- angular - 有没有办法标记在组件的 html 部分中使用的组件方法?
- c# - 使用 XML Reader 从 RSS 提要中获取特定信息到 winform
- css - 如何使滚动捕捉以在 CSS 中的水平容器上自动滚动?
- php - PhpStorm - 有没有办法将 PHPDoc 转换为类型提示并返回类型声明?
- compression - 奥丁失败!LZ4 无效
- android - 在 Kotlin 中处理事件总线的通用侦听器
- java - 如何管理微服务架构中的多对多关系?
- c - 如何在包含预处理器指令中包含 makefile 变量
- javascript - 为什么 Facebook 登录 API 不询问电子邮件访问权限?
- c# - 将 TaskRequestItem 的 UserProperties 传递到 Outlook 应用程序(VSTO 插件)时丢失