【问题标题】:Lua - Concatinate several arguments passed into a function, until condition is met, then pass string to next functionLua - 连接传递给函数的几个参数,直到满足条件,然后将字符串传递给下一个函数
【发布时间】:2020-05-27 14:19:10
【问题描述】:

pvMessage 是从另一个函数发送的,消息通常几乎立即分几部分出现。我正在寻找存储 pvMessages 并将消息连接到最后。因此创建了一个包含所有部分的主字符串。

Example.
pvMessage #1 = thisispart1msg
pvMessage #2 = now part two is being received
pvMessage #3 = Part 3

MasterMessage = thisispart1msgnow part two is being receivedPart 3

我已尝试多次尝试解决此问题。事实证明,在函数之外存储消息比我更难,但我一直在覆盖之前的消息。

    function ProcessClientMessage( pvMessage ) 
         if StartMessage == "" then
            StartMessage = pvMessage                
            pvMessage = ""
         end

         if pvMessage ~= "" then
             if MiddleMessage == "" then
                MiddleMessage = pvMessage
                pvMessage = StartMessage .. MiddleMessage
                pvMessage = ""
             end
          end

         if pvMessage ~= "" then
            if EndMessage == "" then
                EndMessage = pvMessage
                pvMessage = StartMessage .. MiddleMessage .. EndMessage
                pvMessage = ""
             end
         end

         if pvMessage ~= "" then
            ProcessClientMessageReset()
         end 
    end

【问题讨论】:

    标签: function lua arguments


    【解决方案1】:

    您可以使用“或”赋值来简化全局变量的初始化,然后将字符串连接到结果。考虑:

    function ProcessClientMessage(msg)
        msg_global_ = (msg_global_ or "")..msg
        print(msg_global_) -- Just for debug purposes so we can print each step
    end
    
    do
        ProcessClientMessage("thisispart1msg")
        ProcessClientMessage("now part two is being received")
        ProcessClientMessage("Part 3")
    end
    

    变量msg_global_ 包含正在构建的字符串。如果它还没有被添加,那么它将是 nil。在这种情况下,or "" 将被执行并且默认字符串为空。

    然后我们只需附加字符串msg

    输出如下:

    thisispart1msg
    thisispart1msgnow part two is being received
    thisispart1msgnow part two is being receivedPart 3
    

    当您实际处理消息时,只需将全局变量设置为 nil 即可。

    【讨论】:

      【解决方案2】:

      这个问题也可以用协程解决:

      local function consumer(consume)
         print(consume()..consume()..consume())
         return consumer(consume)
      end
      
      local process = coroutine.wrap(consumer)
      process(coroutine.yield)
      
      process('foo')
      process('bar')
      process('baz')
      
      process('hello')
      process('world')
      process('test')
      

      编辑:正如 Egor 所指出的,评估的顺序在技术上没有定义(尽管在我知道的每个 Lua 实现中它都是从左到右的)所以即使你的解释器正在做@987654322,这里有一个替代方案也可以工作@-like 优化:

      local function consumer(consume)
         local a = consume()
         local b = consume()
         local c = consume()
         print(a .. b .. c)
         return consumer(consume)
      end
      

      【讨论】:

      • Lua 不保证在表达式 f1()..f2() 中函数 f1 会首先被调用,然后 f2 会被调用。尽管对于当前的实现来说确实如此。
      • 当我看到你的方法时,我意识到还有其他因素需要考虑。如果我不知道我期待多少物品怎么办?它不应该超过 4,但是如果它是 1、2、3 会发生什么。我确实知道一切都应该几乎同时出现,因此可以使用计时器来选择退出,例如 1000 毫秒。选择退出的另一个选项,我知道必须存在的三个不同的关键短语,即“Clip%=”、“Next%=" 和“Previous%="。如果没有 3 个语句并且时间已经过去,请从内存中清除所有语句。等待下次通讯。有什么建议吗?
      【解决方案3】:

      如果您总是要连接三个部分,则可能会这样:

      local buffer = {}
      local function ProcessClientMessage(pvMessage) 
        if #buffer < 3 then
          table.insert(buffer, pvMessage)
        else
          --ProcessClientMessageReset(table.concat(buffer, ""))
          print(table.concat(buffer, ""))
          buffer = {}
        end
      end
      ProcessClientMessage("thisispart1msg")
      ProcessClientMessage("now part two is being received")
      ProcessClientMessage("Part 3")
      
      ProcessClientMessage("more thisispart1msg")
      ProcessClientMessage("some now part two is being received")
      ProcessClientMessage("Part 4")
      

      这应该打印出来:

      thisispart1msgnow part two is being receivedPart 3
      more thisispart1msgsome now part two is being receivedPart 4
      

      【讨论】:

      • 当我看到你的方法时,我意识到还有其他因素需要考虑。如果我不知道我期待多少物品怎么办?它不应该超过 4,但是如果它是 1,2,3 会发生什么。我确实知道一切都应该几乎同时出现,因此可以使用计时器来选择退出,例如 1000 毫秒。选择退出的另一个选项,我知道必须存在的三个不同的关键短语,即“Clip%=”、“Next%=" 和“Previous%="。如果没有 3 个语句并且时间已过,请从内存中清除所有语句。等待下次通讯。有什么建议吗?
      • 没有可靠的方法可以根据时间间隔执行此操作。您可以设置信号,但只能以系统相关的方式完成。我想如果你能描述为什么你想这样做,也许我们可以建议一个更好的选择,因为它似乎是XY problem的一个例子。
      • 我正在接收来自 TCP 客户端的消息。有三个消息作为一个字符串同时出现,但由于数据包、传输等原因经常被分解,因此需要重新组合到主流中。三个标识符“Clip%=”、“Next%=”和“Previous%=”需要出现在主字符串中,它要求每个标识符都存在。我正在尝试解决“如果不存在”标识符会发生什么,因此主消息不完整。我需要根据完整的标识符构建有效的子字符串,或者转储主字符串。
      • 我认为最好的方法是发送长度或使用行终止符 (CR/LF) 发送消息,以便在接收端正确解码。
      猜你喜欢
      • 2018-01-15
      • 2011-05-12
      • 1970-01-01
      • 1970-01-01
      • 2021-12-12
      • 1970-01-01
      • 2018-06-03
      • 1970-01-01
      • 2012-09-25
      相关资源
      最近更新 更多