【问题标题】:Why is `i` being taken as 1 always in for-loop为什么`i`总是在for循环中被视为1
【发布时间】:2012-07-19 08:25:46
【问题描述】:

我编写了这个简单的脚本来更新 MySQL 中的表。为此,我创建了一个 for 循环并尝试了以下操作 (codepad link):

sUpdate = [[UPDATE `latest`
SET `date` = '%s'
WHERE `date` = '%s'
AND `fid` > 50000]]

for i = 1, 12 do
  print( i )
  sOldDate = "2009-"..tostring(i).."-10"
  sNewDate = "2010-09-"..tostring(i)
  sUpdate = string.format( sUpdate, sNewDate, sOldDate )
  print( sUpdate )
end

输出如下:

1
UPDATE `latest`
SET `date` = '2010-09-1'
WHERE `date` = '2009-1-10'
AND `fid` > 50000
2
UPDATE `latest`
SET `date` = '2010-09-1'
WHERE `date` = '2009-1-10'
AND `fid` > 50000
3
UPDATE `latest`
SET `date` = '2010-09-1'
WHERE `date` = '2009-1-10'
AND `fid` > 50000
4
UPDATE `latest`
SET `date` = '2010-09-1'
WHERE `date` = '2009-1-10'
AND `fid` > 50000
5
UPDATE `latest`
SET `date` = '2010-09-1'
WHERE `date` = '2009-1-10'
AND `fid` > 50000
6
UPDATE `latest`
SET `date` = '2010-09-1'
WHERE `date` = '2009-1-10'
AND `fid` > 50000
7
UPDATE `latest`
SET `date` = '2010-09-1'
WHERE `date` = '2009-1-10'
AND `fid` > 50000
8
UPDATE `latest`
SET `date` = '2010-09-1'
WHERE `date` = '2009-1-10'
AND `fid` > 50000
9
UPDATE `latest`
SET `date` = '2010-09-1'
WHERE `date` = '2009-1-10'
AND `fid` > 50000
10
UPDATE `latest`
SET `date` = '2010-09-1'
WHERE `date` = '2009-1-10'
AND `fid` > 50000
11
UPDATE `latest`
SET `date` = '2010-09-1'
WHERE `date` = '2009-1-10'
AND `fid` > 50000
12
UPDATE `latest`
SET `date` = '2010-09-1'
WHERE `date` = '2009-1-10'
AND `fid` > 50000

如您所见,print(i) 打印得很好,但sOldDatesNewDate 都被视为1。然后我把sOldDatesNewDate改成如下:

sOldDate = string.format("2009-%d-10", i)
sNewDate = string.format("2010-09-%d", i)

我仍然得到两个日期的输出:2009-1-102010-09-1,如 here 所示。

这个循环可能有什么问题。我在这样的循环上工作了很长时间,直到今天它们才让我失望。

我认为这只是我无法识别的一些愚蠢的错误。任何帮助表示赞赏。

【问题讨论】:

  • 我不是 lua 专家,但我在 for 循环中设置了 i=1,并且似乎从不递增,即 i++
  • @NicholasKing Luas for 循环就是这样编程的。检查PIL
  • 我只是在阅读和围绕 Lua 循环,可以看到我的评论是不正确的,就像我说没有 Lua 专家,更多的是观察而不是答案。不过感谢您的更正。 :-)

标签: for-loop lua string-formatting increment


【解决方案1】:

是的,问题是你每次都覆盖sUpdate

第一次,你会覆盖字符串占位符%s,之后字符串就不会再改变了。

尝试重命名内部sUpdate。而且我认为您希望所有变量都为local

local sUpdate = [[UPDATE `latest`
SET `date` = '%s'
WHERE `date` = '%s'
AND `fid` > 50000]]

for i = 1, 12 do
  print( i )
  local sOldDate = "2009-"..tostring(i).."-10"
  local sNewDate = "2010-09-"..tostring(i)
  local sUpdate = string.format( sUpdate, sNewDate, sOldDate )
  print( sUpdate )
end

编辑:正如你在上面看到的,我保留了你的变量名,但内部的sUpdate 不会影响外部的,因为它被声明为local。 Lua 中的所有变量默认都是全局变量,因此最好确保使用 local 声明局部变量。我会选择使用不同的变量名称,例如:

local sUpdateTemplate = [[UPDATE `latest`
SET `date` = '%s'
WHERE `date` = '%s'
AND `fid` > 50000]]

for i = 1, 12 do
  print( i )
  local sOldDate = "2009-"..tostring(i).."-10"
  local sNewDate = "2010-09-"..tostring(i)
  local sUpdate = string.format( sUpdateTemplate, sNewDate, sOldDate )
  print( sUpdate )
end

【讨论】:

  • 嗯,正如我所说,我犯了一个愚蠢的错误。我通常在循环内声明 sUpdate,因此从未遇到任何麻烦。感谢您的建议。 :)
  • 另外,我希望你不介意我选择 furq 的答案而不是你的答案,因为他是 SO 新手,需要一些分数。 ^_^
  • 我认为您应该为后代选择您认为最好的答案。
【解决方案2】:

如前所述,您需要在循环内重命名 sUpdate 以避免覆盖外部的并破坏 string.format()。然后,您可以在 string.format() 中使用 %02d 将数字零填充到长度至少为两位数:

local sUpdate = [[UPDATE `latest`
SET `date` = '%s'
WHERE `date` = '%s'
AND `fid` > 50000]]

for i = 1, 12 do
  print( i )
  local sOldDate = string.format("2010-%02d-10", i)
  local sNewDate = string.format("2010-09-%02d", i)
  local update = string.format( sUpdate, sNewDate, sOldDate )
  print( update )
end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-08-09
    • 2016-10-16
    • 2021-12-02
    • 2020-10-30
    • 1970-01-01
    • 2017-05-17
    • 2011-06-14
    相关资源
    最近更新 更多