これは私がしばらくの間、少し苛立たせられた質問であり、答えを探すために逃げたことがありません。
しかし、少なくとも質問をすることができ、おそらく誰かが説明できると思った。
基本的に私が働いた多くの言語は、構文糖を利用して記述します(C++の構文を使用):
int main() {
int a = 2;
a += 3; // a=a+3
}
luaでは+=
は定義されていないので、a=a+3
、これもまた構文糖に関するものです。次のような「意味のある」変数名を使用する場合:bleed_damage_over_time
または何かを書くのが面倒になり始めるもの:
bleed_damage_over_time = bleed_damage_over_time + added_bleed_damage_over_time
の代わりに:
bleed_damage_over_time += added_bleed_damage_over_time
したがって、ニースのソリューションがない場合、これを解決する方法を知りたくありません。その場合、もちろんそれを聞くことに興味があります。むしろ、luaがこの構文糖を実装していない理由です。
これは私の側の単なる当て推量ですが、次のとおりです。
1。シングルパスコンパイラでこれを実装するのは難しい
Luaのバイトコードコンパイラは、すぐにコードを生成するシングルパス再帰降下パーサーとして実装されます。別のAST構造に解析し、2回目のパスでそれをバイトコードに変換しません。
これにより、文法とセマンティクスにいくつかの制限が強制されます。特に、このモデルでは、任意の先読みまたは前方参照を必要とするものをサポートするのは非常に困難です。これは、割り当ての解析がすでに困難であることを意味します。次のようなものを考えます:
foo.bar.baz = "value"
foo.bar.baz
を解析しているとき、そのコードを解析して生成した後、=
をヒットするまで、実際に割り当てを解析していることに気付かないでしょう。このため、Luaのコンパイラは、割り当てを処理するためだけにかなり複雑です。
自己割り当てをサポートすると、さらに難しくなります。何かのようなもの:
foo.bar.baz += "value"
翻訳する必要があります:
foo.bar.baz = foo.bar.baz + "value"
しかし、コンパイラが=
に到達した時点で、foo.bar.baz
についてはすでに忘れられています。可能ですが、簡単ではありません。
2。文法でニースを再生できない場合があります
Luaには、実際には文法にステートメントや行区切り記号はありません。空白は無視され、必須のセミコロンはありません。できるよ:
io.write("one")
io.write("two")
または:
io.write("one") io.write("two")
また、Luaも両方に満足しています。そのような文法を明確に保つことは難しい。よくわかりませんが、自己代入演算子mayでそれが難しくなります。
。複数の割り当てではニースを再生しません
Luaは次のような複数の割り当てをサポートしています。
a, b, c = someFnThatReturnsThreeValues()
あなたがやろうとした場合、それがどういう意味なのかさえ私には分かりません:
a, b, c += someFnThatReturnsThreeValues()
自己割り当て演算子を単一の割り当てに制限することもできますが、その後、人々が知っておくべき奇妙なコーナーケースを追加しました。
これらすべてにより、自己割り当て演算子が上記の問題に対処するのに十分なほど有用であることはまったく明確ではありません。
Luaが自己割り当て演算子を持たないもう1つの理由は、テーブルへのアクセスがメタテーブルでオーバーロードされ、任意の副作用が発生する可能性があることです。自己割り当ての場合、脱糖することを選択する必要があります
foo.bar.baz += 2
に
foo.bar.baz = foo.bar.baz + 2
またはに
local tmp = foo.bar
tmp.baz = tmp.baz + 2
最初のバージョンはfoo
の__index
メタメソッドを2回実行しますが、2番目のバージョンは1回だけ実行します。言語に自己割り当てを含めず、明示的にすることを強制すると、このあいまいさを回避できます。