【问题标题】:V-REP's Lua `tonumber` returns nil on LinuxV-REP 的 Lua `tonumber` 在 Linux 上返回 nil
【发布时间】:2016-04-05 21:31:30
【问题描述】:

我们开发了一个简单的V-REP 模拟,它在 OS X 上运行良好,但在 Linux (Ubuntu 15.04) 上运行良好。 Lua 被用作主要的脚本语言。

我们附上了以下代码(返回值在 cmets 中),不幸的是在 Linux 上返回 nil(但在 OS X 上将 e[3] 转换为数字没有问题):

e[3]                   -- -0.677782532263
type(e[3])             -- string
type(tonumber(e[3]))   -- nil

真正有趣的是,前面的代码在 Lua 5.2.3 控制台(OS X 和 Linux)中可以正常工作。但是,在 Linux 上运行时,V-REP 无法正确地将字符串转换为数字。

我们尝试了32b and 64b V-REP versions(今天下载),结果完全相同 - nils。你能指出我们缺少的一些东西吗? Lua 和 V-REP 都不是我们每天都在使用的工具。

编辑 1: 我使用 Ubuntu 15.04。 V-REP 使用 Lua 5.1,My Lua 版本:

$ apt-cache policy lua5.1
lua5.1:
  Installed: 5.1.5-7.1
  Candidate: 5.1.5-7.1
  Version table:
 *** 5.1.5-7.1 0
        500 http://cz.archive.ubuntu.com/ubuntu/ vivid/main amd64 Packages
        100 /var/lib/dpkg/status

在控制台中,我尝试了以下操作:

$ lua
Lua 5.1.5  Copyright (C) 1994-2012 Lua.org, PUC-Rio
> e={[3]="-0.677782532263"}; print(e[3], type(e[3]), tonumber(e[3]), type(tonumber(e[3])))
-0.677782532263 string  -0.677782532263 number

【问题讨论】:

  • 你真的把Nil打印出来了吗?还是nil?当发生这种情况时,您确定在 OS X 和 linux 上使用相同版本的 lua?发生这种情况时,前两行在 OS X 和 linux 上都输出相同的值?
  • 你好 Etan,我们得到nil,两个平台上的版本相同,关于输出 - 值在 python 中动态创建并通过远程 api 发送到 vrep(和 lua),所以它们不是相同的确切值,但错误根本不会在 os x 上发生,而是在 linux 上发生在所有传入的浮点数上。
  • @EtanReisner 和 Gyfis 写的完全一样。
  • 如果你尝试print(("%q"):format(e[3])),你会从e[3] 的价值中得到什么?这是什么linux发行版?究竟是什么lua包?如果您手动尝试,您能否使该值在 lua 本身(没有 vrep)中工作? (即e={[3]="-0.677782532263"}; print(e[3], type(e[3]), tonumber(e[3]))?)
  • @EtanReisner 请查看我的编辑 1 和答案。它似乎可以在控制台中使用。

标签: lua type-conversion multiplatform


【解决方案1】:

该错误是由于 V-REP 使用 Lua 5.1 造成的,并且我们测试它的计算机具有不同的数字区域设置(Linux 有 @987654321 @ 并且 mac 可能有 en_US)。

这意味着 Mac 上的 Lua 将字符串中的浮点数识别为数字,但具有不同语言环境的 Linux 上的 Lua 没有 - 它没有 逗号(例如-3,513)语言环境所需的小数分隔符,因此它返回 nil 进行转换。

解决方法是在将 vrep 运行到 en_US 语言环境之前设置 LC_NUMERIC 标志,如下所示:

...$ LC_NUMERIC=en_US.UTF-8 ./vrep

这将强制语言环境基于点,并使 Lua 能够识别数字。

感谢 @Etan 提供的所有帮助以及从正确的方向解决问题。

【讨论】:

  • 像魅力一样工作。感谢您的出色解决方案!
【解决方案2】:

另一种从 lua 代码设置语言环境的方法,例如 os.setlocale("C")

并非所有系统都可以在启动时更改任意应用程序的区域设置,有时需要更改整个系统的区域设置,这对其他应用程序可能不方便。如果使用 V-REP 分发的脚本以与 XML 文件相同的方式分发,其中分隔符是句点,而不是逗号,那么在调用 tonumber 函数之前,应该从 LUA 安装正确的控制台是合乎逻辑的而不是在外面,通过开放环境的变量。

LUA 文档清楚地描述了 os.setLocale 函数的用途,并明确指出它会影响字符串到数字的转换。并指出在调用转换函数之前需要确保设置正确。

此外,在自身内部更改语言环境的脚本更具可移植性,因为不需要启动人员知道应该从外部指定 V-REP 的哪些环境变量。

【讨论】:

  • 好吧,据我了解,接受的答案确实将语言环境设置为解决方案。所以它并没有完全关闭。尽管如此,就目前而言,这个答案并不是很有用。我建议进行大量编辑或转换为评论。
猜你喜欢
  • 2021-03-05
  • 1970-01-01
  • 2018-05-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-15
  • 2018-09-16
  • 2013-09-02
相关资源
最近更新 更多