Lua 和序列化闭包

2024-04-15

我正在尝试序列化和反序列化 Lua 闭包

我的基本理解是下面的工厂应该生成闭包(并且Lua在函数和闭包之间没有太多区别——即没有类型“闭包”)

> function ffactory(x) return function() return x end end
> f1 = ffactory(5)
> print(f1())
5                        <-- so far so good
> s = string.dump(f1)
> f2 = load(s)
> print(f2())
table: 00000000002F7BA0  <-- expected the integer 5
> print(f2()==_ENV)
true                     <-- definitely didn't expect this!

我预计整数 5 会被序列化f1。或者如果string.dump无法处理关闭,我预计会出现错误。

通过轻微的改变,我得到了完全不同的结果(但更多的是我的预期)。看起来像f2确实是一个闭包,但 string.dump 在序列化时并未尝试序列化 x 的值。

The docs http://www.lua.org/manual/5.2/manual.html#pdf-string.dump对我帮助不大。 (“……具有新的上值”是什么意思?)

> function ffactory(x) return function() return x+1 end end
> f1 = ffactory(5)
> print(f1())
6                        <-- good
> s = string.dump(f1)
> f2 = load(s)
> print(f2())
stdin:1: attempt to perform arithmetic on upvalue 'x' (a table value)
stack traceback:
        stdin:1: in function 'f2'
        stdin:1: in main chunk
        [C]: in ?

您可以执行类似的操作来保存/恢复这些上值(请注意,它不处理不同函数之间共享的上值):

local function capture(func)
  local vars = {}
  local i = 1
  while true do
    local name, value = debug.getupvalue(func, i)
    if not name then break end
    vars[i] = value
    i = i + 1
  end
  return vars
end

local function restore(func, vars)
  for i, value in ipairs(vars) do
    debug.setupvalue(func, i, value)
  end
end  

function ffactory(x) return function() return x end end
local f1 = ffactory(5)
local f2 = (loadstring or load)(string.dump(f1))
restore(f2, capture(f1)) --<-- this restored upvalues from f1 for f2

print(f1(), f2())

这在 Lua 5.1 和 Lua 5.2 下都有效。

如果您进行更改,请注意一个有趣的结果ffactory稍微(添加math.abs(0);任何以任何方式使用全局表的东西都可以):

function ffactory(x) return function() math.abs(0) return x end end

现在,如果你恢复 upvalues,你会得到相同的结果,但如果你不恢复 upvalues,你会在 Lua 5.2 下得到一个运行时错误:

lua.exe: upvalues.lua:19: attempt to index upvalue '_ENV' (a nil value)
stack traceback:
upvalues.lua:19: in function 'f2'
upvalues.lua:24: in main chunk
[C]: in ?
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Lua 和序列化闭包 的相关文章

  • 访问修改后的关闭

    string files new string 2 files 0 ThinkFarAhead Example Settings Configuration Local xml files 1 ThinkFarAhead Example S
  • JavaScript 闭包语法

    这些结构之间有什么区别 优点 缺点 如果有 new function obj console log obj extObj vs function obj console log obj extObj 第一个返回对匿名构造函数的新构造实例的
  • 如何访问废弃的函数参数?

    在 Lua 中 调用带有多余参数的函数将简单地丢弃这些参数 有没有可能与debug库来访问这些被丢弃的参数 我不是在寻找可变参数函数 function test local info debug getinfo 1 u print info
  • Lua:冒号符号、“自我”和函数定义与调用

    我对定义 调用 Lua 函数时使用的冒号表示法感到非常困惑 我以为我已经明白了 直到我看到这段代码 function string PatternSafe str return str gsub pattern escape replace
  • 类型提示闭包参数

    通过 PHP 中的类型提示 是否可以对闭包的参数进行类型提示 例如 function some function Closure
  • Lua中如何对数字表求和?

    Lua有内置的吗sum 功能 我似乎找不到一个 我几乎翻遍了文档中的所有地方 或许table sum 或类似的东西 以遵循当前的约定 但由于我找不到它 我不得不实现它 function sum t local sum 0 for k v i
  • 我应该用 C++ 封装 Lua 代码的哪些代码?

    我终于将 LuaBind 配置为与我的 C 项目一起使用 我最近发现 Tiled 地图编辑器可以选择将文件导出为 lua 所以我想尝试一下 我将使用什么代码来封装下面粘贴的代码以使其与我的 C RPG 项目一起使用 return versi
  • 为什么 LuaJIT 和 Lua 中的数字舍入格式不同?

    Using string format 据说遵循 Csprintf 在 LuaJIT 轮次中格式化数字与我尝试过的所有其他 Lua 解释器不同 lua v Lua 5 4 1 Copyright C 1994 2020 Lua org PU
  • Redis 排序集和解决关系

    我正在使用 Redis 排序集来存储我正在处理的项目的排名 我们没有预料到 我们想要如何处理关系 Redis 按字典顺序对具有相同分数的条目进行排序 但我们想要做的是对具有相同分数的所有条目给予相同的排名 例如在以下情况 redis 127
  • 用于嵌入式服务器的 Web 技术

    我最近开始了一个针对嵌入式设备的新 Web 开发项目 并希望征求一些有关使用技术的建议 该设备将提供 HTML 页面 其中包括用于从 JSON 服务器检索数据的 AJAX 代码 我们暂时使用 Cherokee 作为 Web 服务器 但我们并
  • Redis INCRBY 有限制

    我想知道是否有一种方法可以通过我的应用程序的单次往返在 Redis 中执行此操作 对于给定的键K 其可能值V是范围内的任意整数 A B 基本上 它有上限和下限 When an INCRBY or DECRBY发出命令 例如INCRBY ke
  • Google Closure 事件委托 a'la jQuery live/on

    我需要将事件委托给新创建的元素 我需要将处理程序附加到它们的创建事件 类似于 onCreate 我不想在创建后通过寻址将事件绑定到元素 jQuery element click function 我更喜欢类似的东西 on document
  • Swift:ViewModel 应该是结构体还是类?

    我正在尝试在我的新项目中使用 MVVM 模式 第一次 我创建了所有的视图模型来构建 但是 当我使用闭包实现异步业务逻辑 例如 fetchDataFromNetwork 时 闭包捕获旧视图模型值 然后更新为该值 不是新的视图模型值 这是操场上
  • Lua userdata:无法同时进行数组访问和方法

    我遇到了这个人的问题 Lua userdata数组访问及方法 https stackoverflow com questions 26970316 lua userdata array access and methods 其中 当我设置用
  • 这个作用域/闭包什么时候在 javaScript 中被垃圾回收?

    我正在做一门课程 该课程正在讨论范围 闭包并简要提到垃圾收集 课程中提出一个问题 范围保持多久 答案是 直到 不再有任何提及它 是的 所以我们基本上说的是 是的 闭包有点像对隐藏范围对象的引用 所以只要有一些函数仍然有一个闭包 范围 该范围
  • 确定已编译Lua的编译器版本

    我有一些已编译的 LuaQ 我需要确定用于编译它的确切版本 有什么可能的方法吗 编译的脚本在文件开头有一个标头 4 bytes signature x1bLua 1 byte version 0x51 1 byte format 1 byt
  • 封装的闭包与类?

    我是 JS 来自 C etc 的新手 我突然想到闭包似乎是比类更简单 更方便的处理封装的方法 这段代码似乎给出了一种处理封装的简单方法 function addProperty o var value o get function retu
  • JavaScript:事件处理程序:在哪里声明变量 - 本地变量还是闭包(与开销)?

    我发现自己编写了各种包含事件处理程序的函数 感觉最好在父函数 闭包 的根部声明处理函数所需的变量 特别是如果它们是 jQuery 选择 多个处理程序所需的常量 或者需要一些我不想要的预计算每次触发事件时重复 一个简单的例子 var touc
  • Javascript 闭包与 PHP 闭包,有什么区别?

    JS 中的闭包和 PHP 中的闭包有什么区别 它们的工作方式几乎相同吗 在 PHP 中编写闭包时有什么需要注意的注意事项吗 一个区别是两者如何处理存储执行匿名函数的上下文 JavaScript var a 1 var f function
  • 使用 Yew 回调作为 wasm_bindgen 闭包

    这个问题是为 Yew v0 19 编写的 异步外部 JavaScript 函数可以通过以下方式在 Rust 中使用Closures https rustwasm github io wasm bindgen api wasm bindgen

随机推荐

  • 向 Qt 对话框添加最小化按钮?

    我创建了一个QDialog基于使用 Qt Creator 的应用程序 除了对话框没有最小化按钮之外 一切都很好 我怎样才能添加一个 设计器中有我可以设置的属性吗 您无法自己添加最小化按钮 因为它是由窗口管理器处理的 您可以使用窗口管理器提示
  • Devise_token_auth 冲突?

    使用默认的 api 标签在 Rails 5 中创建了一个新的 API 并使用命令安装了 devise token auth gemrails generate devise token auth install User auth 关于做r
  • JavaScript 未知数量的参数

    在我的项目中 我注册了不同的函数 具有不同数量的参数 作为许多事件的侦听器 当事件发生时 我需要触发相关的函数 我接收以数组形式传递给侦听器方法的参数 而侦听器函数需要每个单独的参数 所以 我正在这样做 但我不喜欢这种方法 想知道是否有一种
  • 修改 Silverlight 3 中新 Popup 控件 (ChildWindow) 的外观/行为

    我想删除 Silverlight 3 中新 Popup 控件的灰色标题 如果这可能的话有什么想法吗 很简单 只需编辑默认的 ChildWindow 样式即可 在 Blend 3 中创建一个 ChildWindow 类型的新项目 右键单击项目
  • 在 Linux 中何时使用 pthread_exit() 以及何时使用 pthread_join()?

    我是 pthreads 的新手 我正在尝试理解它 我看到了一些例子 如下所示 我可以看到main 被 API 阻止pthread exit 而且我见过 main 函数被 API 阻塞的例子pthread join 我无法理解何时使用什么 我
  • Java 调试器:是否可以有选择地挂起线程?

    在我过去作为 C C 程序员的生活中 在某些平台和调试器组合上可以选择性地挂起线程 到达断点后 可以发出命令 或单击 GUI 中的内容 来冻结 解除冻结 挂起 唤醒 线程 在执行进一步的步骤 下一步 运行 继续命令时 挂起的线程将不会执行任
  • 使用 AWS codedeploy 部署 Nodejs 实例的 NPM 问题

    我目前正在尝试通过 Github 和 AWS Codedeploy 将 Nodejs 应用程序自动部署到 EC2 实例 我已按照以下指示进行操作here http docs aws amazon com codedeploy latest
  • Array.size() 与 Array.length

    两者有什么区别 所以我知道array size 是一个函数 而array length是一个属性 是否存在使用其中一种而不是另一种的用例 是不是效率更高 我会想象 length明显更快 因为它是一种属性而不是方法调用 为什么人们会使用较慢的
  • Wordpress Multisite - 无法访问子文件夹站点仪表板

    我是 WordPress 多站点新手 我发现了一个奇怪的问题 我已经安装了 WordPress 的新实例 并使用子文件夹启用了多站点 唯一的问题是当我创建新网站时 它无法正确显示 并且我无法访问新网站仪表板 我已将这些行添加到wp conf
  • 如何在 Power Query M 中发表评论?

    有没有办法注释 M 代码 注释掉代码行或代码块 M 支持两种不同类型的注释 单行注释可以以 开头 您可以使用 注释掉多行或注释掉行中间的文本 例如 1 some comment 2 如果注释位于行尾 则它们似乎会在公式栏中消失 但它们仍然存
  • postgresql 加密

    我有 oracle 数据库可以转移到新的 postgresql 服务器 某些表具有敏感字段 并且这些表均通过 DBMS OBFUSCATION TOOLKIT DESENCRYPT DESENCRYPT 进行加密 问题就在这里 postgr
  • PostgreSQL 和 C# 数据类型

    我搜索了 PostgreSQL 和 C 之间的类型转换表 但没有找到任何内容 如果有时间 我会研究上表上的空单元格 但如果您知道包含这些信息的网页 我非常适合您的帮助 Postgre Type gt C Type bigint gt Int
  • 当 EnableSessionState 为 ReadOnly 时更改会话状态

    我有一个 旧的 ASP NET WebForms 项目 并且我想尽可能将 EnableSessionState 设置为 ReadOnly 以防止会话锁阻止单个用户并发页面加载 在某些页面上 我实际上确实想写入会话状态 通常 只需将那些需要写
  • 在 Chrome 中单步执行 JavaScript 断点时如何查看 DOM?

    在 Chrome DevTools 中 在 源 选项卡中调试 JavaScript 时 在 JS 代码中添加 debugger 行 然后使用 F10 F11 单步执行代码 如何在单步执行代码的同时查看 DOM 如果我的 JS 正在操作 DO
  • 在 onResume/onPause 中重新启动/暂停线程

    我有一个使用 SurfaceView 实现来显示对象的游戏 我有一个线程 它会不时地将 SurfaceView 绘制到屏幕上 游戏正在完全运行 不幸的是 它需要在游戏中断时具有暂停功能 好吧 我知道我需要操纵onResume and onP
  • 从“git diff”中排除单个提交

    大家早 假设我有一系列提交 如下所示 abc000 def111 abc222 def333 abc444 def555 我知道我可以使用 git diff c binary abc000 def555 gt tmp abc000 def5
  • 自动崩溃时重新启动 Docker 容器

    如果容器自动崩溃 我想重新启动它 我不知道该怎么做 我有一个脚本 docker compose deps yml 其中包含 elasticsearch redis nats 和 mongo 我在终端中运行它来进行设置 docker comp
  • 获取Web服务的内容

    我有一个像这样的网址here http www myserver com myservice php param foobar 当我在 Safari 的地址栏中输入该内容时 我会看到类似 错误 或 正常 的结果 那么 如何从代码中正确调用该
  • 有没有一种方法可以从一个方法返回多个整数? [复制]

    这个问题在这里已经有答案了 我有一个这样的方法 private double GetHeight return 2 但我希望能够返回两个不同的数字 例如 2 和 3 有什么方法可以在 C 中做到这一点吗 Yes ValueTuple htt
  • Lua 和序列化闭包

    我正在尝试序列化和反序列化 Lua 闭包 我的基本理解是下面的工厂应该生成闭包 并且Lua在函数和闭包之间没有太多区别 即没有类型 闭包 gt function ffactory x return function return x end