【问题标题】:Lua: Calling functions in own moduleLua:在自己的模块中调用函数
【发布时间】:2016-05-28 02:13:19
【问题描述】:

我为 RTC 创建了一个模块。它看起来像这样:

local moduleName = ...
local M = {}
_G[moduleName] = M

---------- Local variables ---------------------
local id = 0
local address = 0x68


---------- Helper functions --------------------
local function bcdToDec(val)
    local hl=bit.rshift(val, 4)
    local hh=bit.band(val,0xf)
    local hr = string.format("%d%d", hl, hh)
  return string.format("%d%d", hl, hh)
end

local function decToBcd(val)
   local d = string.format("%d",tonumber(val / 10))
   local d1 = tonumber(d*10)
   local d2 = val - d1
   return tonumber(d*16+d2)
end

---------- Module functions --------------------
function M.Init(sda, scl)
    i2c.setup(id, sda, scl, i2c.SLOW)
end


function M.PrintTime()
    i2c.start(id)
    i2c.address(id, address, i2c.TRANSMITTER)
    i2c.write(id, 0x00)
    i2c.stop(id)
    i2c.start(id)
    i2c.address(id, address, i2c.RECEIVER)
    c=i2c.read(id, 7)
    i2c.stop(id)
    s = bcdToDec(string.byte(c,1))
    m = bcdToDec(string.byte(c,2))
    h = bcdToDec(string.byte(c,3))

    time=string.format(" %s:%s:%s", h, m, s)
    print(time);
end

function M.PrintDate()
    i2c.start(id)
    i2c.address(id, address, i2c.TRANSMITTER)
    i2c.write(id, 0x00)
    i2c.stop(id)
    i2c.start(id)
    i2c.address(id, address, i2c.RECEIVER)
    c=i2c.read(id, 7)
    i2c.stop(id)
    s = bcdToDec(string.byte(c,1))
    m = bcdToDec(string.byte(c,2))
    h = bcdToDec(string.byte(c,3))
    wkd = bcdToDec(string.byte(c,4))
    day = bcdToDec(string.byte(c,5))
    month = bcdToDec(string.byte(c,6))
    year = bcdToDec(string.byte(c,7))

    time=string.format(" %s.%s.%s", day, month, year)
    print(time);
end

return M

我将此文件保存为“ds3231_m.lua”。从另一个文件调用函数的工作方式如下:

m = require 'ds3231_m'
m.Init(2,1)   --sda, scl = 2, 1
m.PrintTime()
--m.PrintDate()
package.loaded.ds3231_m = Nil

还有

m = require 'ds3231_m'
m.Init(2,1)   --sda, scl = 2, 1
--m.PrintTime()
m.PrintDate()
package.loaded.ds3231_m = Nil

但是当我尝试调用这两个函数时:

m = require 'ds3231_m'
m.Init(2,1)   --sda, scl = 2, 1
m.PrintTime()
m.PrintDate()
package.loaded.ds3231_m = Nil

我收到一个错误:

test.lua:4: attempt to call field 'PrintDate' (a nil value)

谁能告诉我怎么回事?

非常感谢您!

问候

【问题讨论】:

    标签: lua


    【解决方案1】:

    在 PrintTime(和 PrintDate)中,您正在执行 m = something。这确实会从 m = require(...) 覆盖您的 m。 您应该在这些函数中使用本地变量:

    function M.PrintTime()
        i2c.start(id)
        i2c.address(id, address, i2c.TRANSMITTER)
        i2c.write(id, 0x00)
        i2c.stop(id)
        i2c.start(id)
        i2c.address(id, address, i2c.RECEIVER)
        local c=i2c.read(id, 7)
        i2c.stop(id)
        local s = bcdToDec(string.byte(c,1))
        local m = bcdToDec(string.byte(c,2))
        local h = bcdToDec(string.byte(c,3))
    
        local time=string.format(" %s:%s:%s", h, m, s)
        print(time);
    end
    

    这样,您将不会编辑任何全局变量。也对 PrintDate 执行相同操作。

    (如果您使用other_name_than_m = require(...),您不会注意到,但print(m) 仍会打印一个数字,即某事的分钟数)

    【讨论】:

    • 非常感谢,有时候解决办法就是这么简单:)
    • 他可以/应该也可能使用local m = require 'ds3231_m'。不过,这取决于他需要什么。
    • 他可能应该,但这并不重要。在函数内部,对于临时变量,您应该使用局部变量。他在主要剧本中的所作所为取决于他。 (虽然在大多数情况下本地人更好)
    • @mfxfx1 如果此答案对您有所帮助,请务必按绿色复选标记接受!这有助于未来有类似问题的读者像您一样找到答案!
    猜你喜欢
    • 2016-05-11
    • 2018-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-07
    • 1970-01-01
    • 1970-01-01
    • 2016-07-23
    相关资源
    最近更新 更多