1

次のようなテーブルを返すヘルパー関数があります。

function of_type(expected_type)
    return {
        expected = expected_type,
        matches = function(value) return type(value) == expected_type end,
        describe = "type " .. expected_type
    }
end

これは他のマッチャーでは問題ありませんでしたが、ここでは、関数が呼び出されtype(value)たときに同じテーブルのフィールドに保存したいと思います。matchesこのようなもの:

function of_type(expected_type)
    return {
        expected = expected_type,
        mismatch = nil, -- set it to nil on initialization
        matches = function(value) 
            mismatch = type(value)  -- how to do this?
            return type(value) == expected_type
        end,
        describe = "type " .. expected_type
    }
end

これは可能ですか?

4

2 に答える 2

2

はい。ただし、ステップに分割する必要があります。

function of_type(expected_type)
    local tbl = {
        expected = expected_type,
        mismatch = nil, -- set it to nil on initialization
        describe = "type " .. expected_type
    }
    tbl.matches = function(value) 
        tbl.mismatch = type(value)
        return type(value) == tbl.expected
    end
    return tbl
end

-- testing it
local foo = of_type("string")
print(foo.matches(1), foo.matches("1"))

false trueこれは、期待どおりに出力されるはずです。

基本的に、 (「upvalue」と呼ばれる)tbl.matchesへの参照を格納tblし、そのテーブル内のすべてのフィールドを変更できます (それ自体への参照を含む)。

これを行う別の方法は次のとおりです (tbl.matches 関数の変更に注意してください)。それを上位値としてキャプチャする代わりに、セマンティックを使用して暗黙的なパラメーターとしてtbl:method渡すことができます。tblself

    function of_type(expected_type)
        local tbl = {
            expected = expected_type,
            mismatch = nil, -- set it to nil on initialization
            describe = "type " .. expected_type
        }
        function tbl:matches(value) 
                self.mismatch = type(value)  -- how to do this?
                return type(value) == self.expected
            end
        return tbl
    end

local foo = of_type("string")
print(foo:matches(1), foo:matches("1"))

これにより、同じ結果が出力されます。最初のパラメーターとして渡されるfoo:matches表記法を使用していることに注意してください (メソッド内の参照)。これは を使用する場合と同じです。fooselffoo.matches(foo, 1)

于 2012-09-20T15:25:29.447 に答える
1

あなたはそうしない。テーブルのコピーを保存したり、関数にテーブルをパラメーターとして渡したりする必要はありません。テーブル コンストラクターのすべてのステートメントが処理されるまで、テーブルはまだ存在しません。また、(この関数内の) どこにも格納していないため、関数はそれを見つけるために名前を付けることができません。

そのため、ほんの一瞬でも名前を付ける必要があります。

function of_type(expected_type)
  local temp = nil
  temp = {
        expected = expected_type,
        mismatch = nil, -- set it to nil on initialization
        matches = function(value) 
            temp.mismatch = type(value)  -- Like this
            return type(value) == expected_type
        end,
        describe = "type " .. expected_type
    }
  return temp
end

これは、Lua が上位値として保存tempされるため機能します。したがって、作成している関数はtemp、テーブルの値に設定した場合などに、 に変更が加えられます。これはローカル変数であるため、この関数の外からは見えません。

于 2012-09-20T15:26:56.590 に答える