book icon indicating copy to clipboard operation
book copied to clipboard

「シャローコピー=参照の値渡し」と誤解した読者でも、疑問なくシャローコピーとディープコピーを理解できるように改善しませんか?

Open apikmin opened this issue 2 years ago • 7 comments

(初心者のため勘違いしていたら申し訳ありません) シャローコピー、ディープコピーの定義が言語間で異なるため、混乱しています。 私はJavaから来ましたが、Javaではシャローコピーは参照情報のコピーを、ディープコピーは実体のコピーを意味すると思っています。 一方、JavaScriptのシャローコピーの定義は、Javaでいうディープコピーを一層目限定で行うものというふうに読めます。

Javaの用語に従ってまとめると、以下のような認識です。       [参照のコピー] [1層目のディープコピー] [2層目以降のディープコピー] Java    ←シャロー→  ←           ディープ         → JavaScript ←  ? →  ←   シャロー  →  ←    ディープ   →

他の単元では他言語から来た人への注意書きがあり大変わかりやすかったので、もし上の認識が正しい場合、コピーに関しても注意書きがあるとわかりやすくなるかと思います。

関連ページ: https://typescriptbook.jp/reference/values-types-variables/array/spread-syntax-for-array

apikmin avatar Feb 26 '23 03:02 apikmin

@apikmin JavaとJavaScriptでどちらもシャローコピーとディープコピーの指す内容に違いはないと思います。もし本書で、違いがあるように思えた箇所がありましたら、どの部分の文章なのかお教えいただければ幸いです😌

suin avatar Feb 26 '23 03:02 suin

・Java 『Java本格入門』, p.418, 第3刷にて、以下のように説明されています。 ”参照型の変数を別の変数に代入するだけの場合、代入によって参照のみがコピーされます。そのため、コピー先の変数のプロパティの値を変更しても、オブジェクトの実体はコピー前のオブジェクトと同一のため、コピー元の変数から見えるオブジェクトの値も書き換わってしまいます。このようなコピーの方法を「シャローコピー」と呼びます。(中略) コピーして複数の異なるオブジェクトを作成したいのであれば、参照をコピーするのではなく、オブジェクト自体をコピーする必要があります。この方法でコピーすると、コピー先の変数のプロパティの値を変更しても、コピー元の変数から参照されるオブジェクトの値は書き換わりません(実体は別オブジェクトのため)。これを「ディープコピー」と呼びます。”

・JavaScript 本書の「配列のスプレッド構文「...」(spread syntax)」にて、以下のように説明されています。 ”配列のコピーを作る際に、スプレッド構文が便利な場合があります。スプレッド構文で作成されたコピーは、元の配列とは異なる実体を持ちます。(中略) 注意点として、この方法は浅いコピー(shallow copy)です。深いコピー(deep copy)ではない点に注意してください。浅いコピーで複製できるのは、1層目の要素だけです。配列の中に配列が入っている場合は、2層目より深くにある配列は、元の配列のものと値を共有します。”

・以上をJavaの用語に従ってまとめると、以下の違いがあるように認識しています。       [参照のコピー] [1層目のディープコピー] [2層目以降のディープコピー] Java    ←シャロー→  ←           ディープ         → JavaScript ←  ? →  ←   シャロー  →  ←    ディープ   →

apikmin avatar Feb 27 '23 02:02 apikmin

ありがとうございます!これを読む限り、JavaとJavaScriptでは指す内容が違ってきそうですね。

本書の誤りの可能性もあるので、調査してから結論をご回答したいと思います!

suin avatar Feb 27 '23 02:02 suin

@apikmin 調査したところ次の結論が得られました。

  • (少なくとも英語圏では) JavaとJavaScriptで「シャローコピー」と「ディープコピー」は同じようなものを指し、対応関係にある
  • ただし、日本語圏ではJavaの参照渡しが「シャローコピー」とする解説がウェブ・商業本問わず存在していて、Javaを使っている人の中にもJavaとJavaScriptで「シャローコピー」が異なるものを指し、対応関係にないと理解する人がいて、いびつな構造になっている

調査の詳細はこちらを御覧ください: https://zenn.dev/suin/scraps/27e2c2663d002e

この結論と頂いたご指摘(下記)を踏まえると、

他の単元では他言語から来た人への注意書きがあり大変わかりやすかったので、もし上の認識が正しい場合、コピーに関しても注意書きがあるとわかりやすくなるかと思います。

「シャローコピー」と「ディープコピー」が指す内容が読者によって異なりそうなので、

  • 本書で言う「シャローコピー」「ディープコピー」の定義を明確にする
  • Javaでは「シャローコピー」が指す内容が人によって異なる

というところに触れたほうがいいのかもしれないと思いました😌

僕の考えは上記のとおりですが、Javaプログラマの読者として@apikmin さんのご意見があればお聞きしたいです!

suin avatar Feb 28 '23 20:02 suin

詳細な調査を実施していただきまして、誠にありがとうございました。 おかげさまで、参照渡し=シャローコピーと誤解していたことに気づくことができました。

一方、質問にて安易に他書を引用したことにより、貴書の範囲外の内容でお手を煩わせてしまい、誠に申し訳ございませんでした。

今後の改善策の一つ目に関して、シャローコピーの定義を明確にする際、参照渡しとの区別への言及があるとわかりやすいかと思います。 二つ目に関して、Java以外の言語でも同様の誤解があるようでしたら、言語の名指しはなしで誤解自体への言及でもよいかもしれません。

ご検討のほどよろしくお願いいたします。

apikmin avatar Mar 02 '23 10:03 apikmin

@apikmin お考えが聞けて嬉しいです。

シャローコピー=参照渡しの誤解は、Javaに限らず他の言語でも見られることが判明しているので、Javaに限った問題ではなそうです。「Javaがおかしい」「他の言語がおかしい」といったニュアンスにならないように誤解に言及したほうがよさそうですね。上で出したアイディアのうち

Javaでは「シャローコピー」が指す内容が人によって異なる

というふうな説明はやめようと思います。

・・・・・

一方、質問にて安易に他書を引用したことにより、貴書の範囲外の内容でお手を煩わせてしまい、誠に申し訳ございませんでした。

これは僕がJava界隈の人からいろいろな意見をいただきたかったがための行動なので、お気になさらないでください🙇🏻‍♂️ むしろ、想定以上に反響があって @apikmin さんにご迷惑がかかってしまったのではないかと反省しております。。

suin avatar Mar 03 '23 09:03 suin

「シャローコピー=参照の値渡し」と誤解した読者でも、疑問なくシャローコピーとディープコピーを理解できるように改善しませんか?

背景

  • 読者の中には、「シャローコピー=参照の値渡し」と誤解している人がいて、サバイバルTypeScriptのシャローコピーの解説がアンジャッシュ状態になることがある

アイディア

  • シャローコピーとディープコピーのページを作る
  • シャローコピーとディープコピーの概念を説明する
  • JavaScriptのシャローコピーのサンプルコードと同等の処理をする、JavaとPHPのシャローコピーのサンプルコードを書く
  • 言語を伏せた上で、シャローコピーに対する誤解が広まっている点に言及する

suin avatar Mar 03 '23 09:03 suin