在通用 `for` 中的 `if false then local x end` 会丢失块的返回值,引发索引超出范围的异常,或者永远无法完成
作者: DRMacIver创建于 2026年9月22日更新于 2026年9月22日
- GopherLua is a Lua5.1 implementation. You should be familiar with the Lua programming language. Have you read the Lua 5.1 reference manual carefully? - [x] GopherLua is a Lua5.1 implementation. In Lua, to keep it simple, it is more important to remove functionalities rather than to add functionalities unlike other languages. If you are going to introduce some new cool functionalities into the GopherLua code base and the functionalities can be implemented by existing APIs, It should be implemented as a library. 1. What version of GopherLua are you using? : v1.1.2, and master (75f4976) 2. What version of Go are you using? : go1.27.1 darwin/arm64 3. What operating system and processor architecture are you using? : macOS 26.6, arm64 4. What did you do? : A generic
forwhose body contains anifwith a constant-false condition and alocaldeclared in its block breaks the code that runs after thatif: depending on what else is in the chunk,return 1returns nothing, the VM panics with a Go index out of range, or the chunk never finishes. The same body with a condition that is false at run time, or under a numericfor, runs correctly: go package main import "context" "fmt" "strings" "time" lua "GitHub.com/yuin/gopher-lua" func run(src string) { L := lua.NewState() defer L.Close() ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) defer cancel() L.SetContext(ctx) fmt.Println(src) if err := L.DoString(src); err != nil { fmt.Println(" error:", strings.SplitN(err.Error(), "\n", 2)[0]) return } fmt.Printf(" returned %d value(s): %v\n", L.GetTop(), L.Get(1)) } func main() { run(for i = 1, 1 do end for k, v in ipairs({1}) do if false then local y end end return 1) run(local n = 0 for k, v in ipairs({1, 2, 3}) do if false then local y end n = n + v end return n) run(for k, v in ipairs({1}) do if false then local y end end return 1) run(local n = 0 for k, v in ipairs({1, 2, 3}) do if v == 9 then local y end n = n + v end return n) run(local n = 0 for i = 1, 3 do if false then local y end n = n + i end return n) } 5. What did you expect to see? : Each chunk returns the value it ends with: 1, 6, 1, 6, 6. 6. What did you see instead? : for i = 1, 1 do end for k, v in ipairs({1}) do if false then local y end end return 1 error: :1: context deadline exceeded local n = 0 for k, v in ipairs({1, 2, 3}) do if false then local y end n = n + v end return n error: runtime error: index out of range [16] with length 16 for k, v in ipairs({1}) do if false then local y end end return 1 returned 0 value(s): nil local n = 0 for k, v in ipairs({1, 2, 3}) do if v == 9 then local y end n = n + v end return n returned 1 value(s): 6 local n = 0 for i = 1, 3 do if false then local y end n = n + i end return n returned 1 value(s): 6
内容来源: yuin/gopher-lua