如何将Lua迭代器无声地失败改写为一个长尾词?

2026-04-01 20:301阅读0评论SEO资讯
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计649个文字,预计阅读时间需要3分钟。

如何将Lua迭代器无声地失败改写为一个长尾词?

我有一个简单的迭代器的简单问题。假设我设计了一个函数`files()`, 它迭代文件夹中的所有文件:`for file in files(/path/to/folder) do print(file) end`。现在,这个看起来很完美,但这里有一个问题:如何处理文件名包含空格的情况?

我有一个简单迭代器的非常简单的问题.

假设我设计了一个函数files(),它迭代文件夹中的所有文件:

for file in files("/path/to/folder") do print(file) end

现在,这似乎很完美,但这里有一个问题:如果文件夹不存在,或者我们没有读取权限怎么办?

我们如何表明这样的错误?

一种解决方案是在这种情况下让files()返回nil,“no read permission”.然后我们可以将调用包装在assert()内的files()中:

如何将Lua迭代器无声地失败改写为一个长尾词?

for file in assert(files("/path/to/folder")) do print(file) end

这似乎解决了这个问题.但是这迫使我们的用户总是使用assert().如果用户不关心错误怎么办?对于这种类型的用户,我们希望我们的文件()表现得就像文件夹是空的一样.但Lua –in case files()表示错误 – 会尝试调用返回的nil,这将导致错误(“尝试调用nil值”).

所以,

我们如何设计一个迭代器,files(),以满足关心错误的用户和不关心错误的用户?

如果不可能,你会建议什么选择?

首先:考虑在文件函数中引发错误(使用错误),而不是返回nil错误消息.这样你就不会忘记断言调用,并且你不会得到令人困惑的“尝试调用零值”错误.

当你不想引发错误时,你可以向文件传递一个额外的布尔参数 – 你应该返回一个空函数(function()结束),而不是在这种情况下调用错误.

更一般的方法如下:

-- an iterator that immediately stops a for loop local function dummy_iter() end -- catch errors and skip for loop in that case function iterpcall( g, ... ) local ok, f, st, var = pcall( g, ... ) if ok then return f, st, var else return dummy_iter end end for file in iterpcall( files, "/path/to/folder" ) do print( file ) for line in iterpcall( io.lines, file ) do -- works for other iterators as well print( line ) end end

上面的iterpcall实现只处理迭代器生成器(文件或io.lines)中引发的错误,而不是迭代器函数(f)本身.你必须用pcall将f包装在一个闭包中才能做到这一点.

本文共计649个文字,预计阅读时间需要3分钟。

如何将Lua迭代器无声地失败改写为一个长尾词?

我有一个简单的迭代器的简单问题。假设我设计了一个函数`files()`, 它迭代文件夹中的所有文件:`for file in files(/path/to/folder) do print(file) end`。现在,这个看起来很完美,但这里有一个问题:如何处理文件名包含空格的情况?

我有一个简单迭代器的非常简单的问题.

假设我设计了一个函数files(),它迭代文件夹中的所有文件:

for file in files("/path/to/folder") do print(file) end

现在,这似乎很完美,但这里有一个问题:如果文件夹不存在,或者我们没有读取权限怎么办?

我们如何表明这样的错误?

一种解决方案是在这种情况下让files()返回nil,“no read permission”.然后我们可以将调用包装在assert()内的files()中:

如何将Lua迭代器无声地失败改写为一个长尾词?

for file in assert(files("/path/to/folder")) do print(file) end

这似乎解决了这个问题.但是这迫使我们的用户总是使用assert().如果用户不关心错误怎么办?对于这种类型的用户,我们希望我们的文件()表现得就像文件夹是空的一样.但Lua –in case files()表示错误 – 会尝试调用返回的nil,这将导致错误(“尝试调用nil值”).

所以,

我们如何设计一个迭代器,files(),以满足关心错误的用户和不关心错误的用户?

如果不可能,你会建议什么选择?

首先:考虑在文件函数中引发错误(使用错误),而不是返回nil错误消息.这样你就不会忘记断言调用,并且你不会得到令人困惑的“尝试调用零值”错误.

当你不想引发错误时,你可以向文件传递一个额外的布尔参数 – 你应该返回一个空函数(function()结束),而不是在这种情况下调用错误.

更一般的方法如下:

-- an iterator that immediately stops a for loop local function dummy_iter() end -- catch errors and skip for loop in that case function iterpcall( g, ... ) local ok, f, st, var = pcall( g, ... ) if ok then return f, st, var else return dummy_iter end end for file in iterpcall( files, "/path/to/folder" ) do print( file ) for line in iterpcall( io.lines, file ) do -- works for other iterators as well print( line ) end end

上面的iterpcall实现只处理迭代器生成器(文件或io.lines)中引发的错误,而不是迭代器函数(f)本身.你必须用pcall将f包装在一个闭包中才能做到这一点.