■まえがき
ぼくが以前いた会社で**「参照型と値型の違いが良く解らない」**という新人君に説明した時の事を、Twitterで呟いたところ非常に解り易いと反響を貰った事がある。
せっかくQiitaを始めたので、こんな小ネタなんかも加筆修正して纏めてみようかと。
(Twitter制限で140字以内に纏めてましたし)
■さっそく本題
ぼくが当時した説明はこんな感じです。
※もちろん、新人向けの簡単な説明なので、メモリ管理の厳密な所とかは端折ってますよ
かんたんな説明
まずエクスプローラを立ち上げて、適当なフォルダを開きます。
「これがまぁ、メモリ領域だとして。」
でもってメモ帳を立ち上げて*(別にSakuraでも秀丸でも何でも良いよ!)*、適当な文面を打ち込んで先のフォルダに保存します。
「これがデータね。newでインスタンス作ったと思えば良い。」
次に、新しいフォルダを開き、
- 保存したテキストファイルを単純にコピーします。
- 保存したテキストファイルのショートカットを作成します。
「こっちのコピーしてきたのが『値型』で、ショートカットの方が『参照型』ね。」
更に解説。
これだけでピンと来てくれる子は中々いないと思うので、以下の説明を続けます。
(相手の反応を伺って、説明を続けるか切り上げるかは要判断)
「コピーもショートカットも、ダブルクリックしてテキスト開いたら同じ内容が出て来るじゃん?
そういう意味では、どちらも『同じデータを持っている』と言えるので、この段階では特に違いは無い。」「開いて見るだけ、つまり『参照』するだけなら両者の違いは(ほぼ)無い。
この段階で違うとしたらメモリの(この場合はHDD容量)の消費量だけ。」「じゃあ、値型と参照型で何が決定的に違うかと言うと、それは『参照』の時じゃなく『編集』の時。
つまりこのメモ帳を開いている状態で、文章を書き換えて保存した時の影響度が違う。」
ここまで言えば頭の回転の早い子は大体理解してくれると思います。
「単純にファイルをコピーした場合、元のデータと同じ内容を持っている新しいファイルが作られる。
これをプログラムに置き換えると、新しいメモリ領域に元のデータの完全な複製が出来上がる訳だ。
元のデータとは別な所に独立した形でデータが作られるので、コピーした方を弄っても元のデータには影響が出ない。」「対してショートカットを作った場合、実際にはファイルが作られる訳では無く、ファイルの場所だけ控えた形になる。
これをプログラムに置き換えると、元のデータの複製が作られる訳じゃなく、元のデータがメモリ上のどこにあるかだけを記憶する。
この『どこにあるか』をアドレス、インスタンス参照、ポインタなんて言ったりするが、とりあえず全部同じものだと思っとけ。」「で、この『どこにあるか』と言う情報は、元のデータの複製を作るよりも遥かにデータ量が小さい。
例えば、ここに家が建ってたとして、全く同じ家を新しく建てるのと住所だけ控えるのとでは全然話が違うだろ?
これが家じゃなくてマンションや高層ビルだったら更に大変な事だが、住所だけなら大した話ではない。
つまり省エネ、省コストなんだな。プログラム的に言えばメモリの節約になる。」
相手の理解の色が広がったら、ざっくり纏めます。
「これが、値型と参照型の違い。」
「簡単に纏めるとこう。
値型は完全なコピーが作られる。その分メモリを消費するが、データの書き換えがコピー元に影響を出さずに済む。
参照型はショートカットみたいなもの。メモリの節約になるが、同じものを共有するのでデータの書き換えが全体に影響する。」「どっちが良いとか悪いとかじゃなくて、適材適所、目的と手段の話になる。
データを編集まで含めて共有したいのであれば参照型が適しているし、
データのコピーを与えたいがそれぞれ独立して編集したい場合は値型が欲しくなる。」「厳密に言えば参照型で値型的コピーを作る事も可能だし、
イミュータブル、不変オブジェクトと言うクラスの作り方もあるし、
難しい話をしていくとまだ色々とあるけどな。」
ちょっとこの文章だけだと解り難い気もしますが、実際にエクスプローラ上でファイル操作して見せながら説明すればきっと理解してくれると思います。
■あとがき
この説明が通り易かったのは哀しいかなもう昔の話。
この説明をした当時はまだスマホが出始めで、持っている人もまだ少ない時期でした。
しかし今はもう端末所有事情が変わっており、持ってるのはスマホやタブレットのみでPCを持っていないと言う人も増えています。
そんな最近のスマホ世代の新人相手に、エクスプローラを使って説明した所でピンと来ないよなぁ、、、。
今の子にも通じる、何かいい説明方法は無いかなぁ?
(´・ω・`)