"attempt to call table" without for

当我调用我写的方法stream,并且用任何表作为参数时,我会得到错误“attempt to call table”。

据我所知,只有在我使用错误的for循环时才会出现此错误,但是在执行的代码中我没有使用for循环...

function stream(input)
  ...
  local function _stream(input)
    local result = {
      _stream = true,
      _data = input._data or input,
      -- 如果没有操作包装,那么没有函数可以访问输入
      -- Intermediate Operations
      concat = function(str) return _concat(input,str) end,
      distinct = function(func) return _distinct(input,func) end,
      filter = function(func) return _filter(input,func) end,
      limit = function(n) return _limit(input,n) end,
      map = function(func) return _map(input,func) end,
      skip = function(n) return _skip(input,n) end,
      sort = function(func) return _sort(input,func) end,
      split = function(func) return _split(input,func) end,
      -- Terminal Operations
      allmatch = function(func) return _allmatch(input,func) end,
      anymatch = function(func) return _anymatch(input,func) end,
      collect = function(coll) return _collect(input,coll) end,
      count = function() return _count(input) end,
      foreach = function(func) return _foreach(input,func) end,
      max = function(func) return _max(input,func) end,
      min = function(func) return _min(input,func) end,
      nonematch = function(func) return _nonematch(input,func) end,
      reduce = function(init,op) return _reduce(input,init,op) end,
      toArray = function() return _toArray(input) end
    }
    return result
  end

  if input == nil then
    error("input 必须是类型为table的,但是是nil")
  elseif type(input) ~= "table" then
    error("input 必须是类型为table的,但是是 "..type(input)..": "..input)
  end
  return _stream(input)
end

table.stream = stream

完整源码 - 较早版本(其中参数因某种原因被删除)

我想使用该方法进行更基于流的编程风格。非常类似于this项目,但不仅适用于数字,还适用于命名键。

点赞
用户1847592
用户1847592

在你的代码中

function stream(input)
  -- ...

  local function _count()
    local count = 0
    for k, v in pairs(input._data) do
      count = count + 1
    end
    return count
  end

  -- ...

  local function _stream(input)
    local result = {
      _stream = true,
      _data = input._data or input,
      -- ...
      count = _count,
      -- ...
    }
    return result
  end

  return _stream(input)
end

print(stream({1,2,3}).count())

创建的对象 _stream(input) 包含 _data 字段,但 input upvalue 仍然指向你的参数 {1,2,3},它没有 _data 字段。

可以通过操作对象而不是输入参数来解决这个问题:

function stream(input)
  -- ...

  local obj

  local function _count()
    local count = 0
    for k, v in pairs(obj._data) do
      count = count + 1
    end
    return count
  end

  -- ...

  local function _stream(input)
    local result = {
      _stream = true,
      _data = input._data or input,
      -- ...
      count = _count,
      -- ...
    }
    return result
  end

  obj = _stream(input)

  return obj
end

print(stream({1,2,3}).count())
2018-03-03 12:24:20