ディープラーニングLua--環境テーブル

Lua言語は、グローバル環境自体をグローバル変数_Gに保存し、グローバル環境内のすべてのグローバル変数の名前を次のように出力します。

ペアのnの場合(_G)印刷(n)終了

  • 動的な名前を持つグローバル変数

別の変数のグローバル変数の取得、

value = load( "return" .. varname)()和

value = _G [varname]も同じ効果があり、後者の方が1桁効率的です。

  • グローバル変数宣言

次のように、グローバル変数を宣言なしで使用して、グローバルテーブルの存在しないすべてのアクセスを検出できます。

setmetatable(_G,{
    __newindex = function (_,n)
        error("attempt to write to undeclared varibale "..n,2)
    end,
    __index = function (_,n)
        error("attempt to read to undeclared varibale "..n,2)
    end,
})

もちろん、rawsetとrawgetを使用してメタメソッドをバイパスすることもできます。

  • 非グローバル変数

次のようなフリーネーム(フリーネーム):xは_ENV.xと同等であり、_ENV自体はローカル変数であり、環境と呼ばれる任意のテーブルです。

Luaがグローバル変数を処理する方法:

すべてのコードをコンパイルする前に、外層にローカル変数_ENVを作成します。

すべてのフリーネームvarは_ENV.varに変換されます。

関数loadは、グローバル環境を使用して、コードセグメントの最初のアップ値を初期化します。これは、lua構文によって内部的に維持されるテーブルです。

  • _ENVを使用する

コードセグメント(ファイル)には_ENV変数があります。_ENV = nilは、後続のコードがグローバル変数に直接アクセスするのを防ぎます。_ENVの主な目的は、コードセグメントが使用される環境を変更することです。次のように、継承を使用して古い環境をロードします。

local newgt = {}
setmetatable(newgt, {__index = _G})
_ENV = newget

割り当てはすべて新しいテーブルで行われます。グローバル変数の変数を変更するために使用できるのは_Gのみです。

  • 環境とモジュール

_ENVは、グローバル変数の汚染を解決します。

  • _EVNとロード

Loadは通常、ロードされたコードセグメントの値_ENVをグローバル環境に初期化します。また、_ENVに別の初期値を指定するためのオプションのパラメーターがあります。

env = {}
loadfile("config.lua","t",env)()

サンドボックスでの実行に似ています。

コードを数回実行します。そのたびに異なる環境で、2つのオプションは次のとおりです。

最初のものはdebug.setupvalue(f、1、env)を使用します

最初のパラメーターは指定された関数、2番目のパラメーターはアップ値インデックス(常に1)、3番目のパラメーターは新しいアップ値です。[デバッグライブラリによっては、可視性ルールを破る]

もう1つは、次のように、ロードされるたびにコードセグメントを変更することです。

lua把所有代码段当做可变长参数函数进行编译,多出来这一行会把传给代码段的第一个参数赋值给_ENV,从而改变环境。

prefix = "_ENV = ...;"
f = loadwithprefix(prefix,io.lines(filename,"*L"))
...
env1 = {}
f(env1)
env2 = {}
f(env2)

 

おすすめ

転載: blog.csdn.net/Momo_Da/article/details/105598511