staticローカル変数とは
C言語とかVB.Netとかには存在する。あとVBAにもあったような気がする。
JavaとかC#とかにはないらしい。
詳細はググれ(なげやり)
私の認識は、
グローバル変数みたいにずっと残るけど、スコープはグローバルじゃなくてローカルな変数
というものです。
スコープは小さくできるなら小さくするのが鉄則だと思うので「値をずっと残しておきたいローカル変数」というシチュエーションで使うんじゃないでしょうか。
とはいえ
「値をずっと残しておきたいローカル変数」
...そんなシチュエーションあるの?
どんなシチュエーション?
みなさんはどのようなシーンで使うかはわかりませんが、
私の場合は、DBや設定ファイルなどに分けている定義データをキャッシュするときに使います。
定義は外に出しておきたいんだけど、毎回取得しにはいきたくないなぁ。。。というときです。
↓VB.Netでいうとこんな感じ
Public Function GetDefiition() As String
Static def As String = String.Empty
If String.IsNullOrEmpty(def) Then
' なんかDBにとりにいく
def = fromDB()
End If
Return def
End Function
他に「こんなときに使うよ」というのがあったら教えてください。
JavaScriptとかC#とかでも使いたい!
基本的には私はC#はVB.Netより優れてると思っているのですが、
このStaticローカル変数、VB.Netにはありますが、C#にはありません。
まぁ、クラス作ってそのメンバ変数にすればそれで事足りるからね。仕方ないね。
でも私はこんだけのことのためにメンバ変数を増やすのは嫌なんです。
「この変数はどこで使ってるのかな? あぁ、ここでしか使っていないか」
とソースコードを追うたびに確認しなきゃいけないのは苦痛です。
JavaScriptにないのは、そもそもあの言語グローバルスコープと関数スコープの変数しかなかったからね。仕方ないね。
なんとかして実現する
はい、クロージャーをつかいます。
クロージャーとはパンとか止める奴のことです(適当)。
C#の場合
public static readonly Func<string> GetDefinition = (new Func<Func<string>>(() =>
{
string def = string.Empty;
return () => string.IsNullOrEmpty(def) ? def = fromDB() : def;
}))();
JavaScriptの場合
const getDefinition = (() => {
let def;
return () => def ? def : def = fromDB();
})();
できた。
実際問題
どうなんでしょうね。
なんだか、他の言語の機能を無理矢理適用したみたいで、ちょっと気持ち悪くはあるんですが。
唐突にソースコード中にこんな記述がでてきたら「え、なにしてんのこいつ」と思う気もします。
でも私は使っています。
ちなみに
JSでは以下のような書き方をしたこともあります。
function getDefinition() {
return getDefinition.data ? getDefinition.data : getDefinition.data = fromDB();
}
これは、JSでは関数もオブジェクトなので、そのメンバ変数を内部で作ってる、ということですね。
これはこれでなるほどと思えるんですが「動的なメンバ変数」であることと、「外部からもアクセスできてしまう」という欠点があります。