定数の話

技術

プログラミング言語の定数の話。ある言語を勉強していて混乱したのと、なんで、言語によってこうも考え方が違うのか、ということを書き綴ってみました。

言語によって定数の書き方が違う

言語が違えば文法も違います。それは当然ですが、なんで定数の書き方ひとつとっても千差万別なのでしょう。おかげですごく混乱します。

memo

paiza.ioの埋め込み機能を使ってコードの表示と実行ができるようにしてあります。ただ、初期状態でコード3行程度しか表示されずにみにくいことがあります。一度実行すると表示領域が広がるようです。

C言語の場合

ある意味シンプル。最初の方に学んだ言語なので、自分にとってのベースの考え方です。

普通の変数の宣言と初期化に一言追加するだけ。定数は定数、変数は変数と別れていてわかりやすく感じるのは贔屓目でしょうか。

Pythonの場合

Pythonの場合大文字で記述。ただし、これはあくまで慣習としてそういうルールにしましょうというだけ。言語としてのサポートはないため、いくらでも上書きできます。

言語としてサポートがないのだから、定数は存在しないと言い切ってしまうのも手だと思うのですが、人間が運用で気をつけなさいという流れです。
すみません、よく運用でカバーしてくださいみたいなことはしてきたので、Pythonを否定する資格がありませんでした。

Rubyの場合

Pythonと同じく大文字の変数名にすれば定数扱いです。ただ、こちらはちゃんと言語としてサポートしているので、上書きするとエラーになります。

やはり言語としてのサポートがある方が良いですよね。ツールでチェックすれば良いだけとも言えますけど。本格的にやるならそういうのも導入しますけど、ちょっと学びたいときには言語標準でエラー出してくれた方がありがたいです。

JavaScriptの場合

C言語と同様にconstが定数です。

ただし、似たようなものとしてletとvarの違いが絡んでくるのでややこしいです。あくまで定数はconstで宣言するもので、再定義も再代入も不可です。

一方で変数を宣言する際にはletとvarがありますが、letは再定義不可、varは再定義可能です。どちらも再代入は問題ありません。どちらにしろletもvarも再定義の扱いだけで再代入は普通に可能な変数です。定数と変数ということをきちんと分ければ混乱はないかと思います。

2021/11/2 補足

厳密にはconstは再代入できない変数であり、「定数=変更できない値」ではない、とのこと。
どういうことかというと、変数に対しては再代入できないので値が不変であり、定数と言えるのですが、const宣言自体はオブジェクトにも指定できます。const宣言したオブジェクトのプロパティは変更できるので定数ではない、という解釈だそうです。

Swiftの場合

Swiftの定数はletで宣言します。変数はvarです。

JavaScriptと似て非なるので注意が必要です。Swiftのletは定数ですので、再定義も再代入もコンパイルエラーです。

わかりやすいのですが、それならC言語等のようにconstで良かったんじゃないかという気がします。letは定数、varは変数なんて字面からは類推できないのでわかりにくいのではないかと思ってしまいます。JavaScriptに似せている感じなのに、根本的には違うものなので「どうしてこうなった」とツッコミを入れたくなります。

Javaの場合

Javaは割とCの影響を受けているはずなのですが、定数についてはfinalキーワードで処理します。わかるけどわからん。

Rustの場合

これがなかなか面倒と言うか難解。どうしてここまで。

Rustの場合も普通の定数はconstです。なお、変数名は小文字でもコンパイルは通りますが、警告が出ます。

静的変数を定義するstaticでも見かけ上は同じような動作をしますが、内部の扱いが全く違うので定数代わりに使うのは不可。定数は素直にconstを使うのが良さそう。

Rustは勉強しようかと思いつつまだあまり手をつけてないので、違いをなんとなくしか理解しておらず、ちゃんとした説明ができない状況です。Rustの場合はミュータブルとイミュータブルという概念があり、それとの組み合わせで同じような動作になっているだけで、本来の意味では定数ではないので使わない、というところでしょうか。

おまけ:C言語番外編

C言語やC++言語の場合、マクロを使うこともできます。定数ではないですし、あまり濫用すべきではないです。

2021-11-02技術プログラミング言語

Posted by woinary