2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

JavaとGoの値渡し/参照渡しを整理する

Last updated at Posted at 2020-02-17

自分はこれまでにJava, Goを勉強してきた。この二言語における値渡し/参照渡しをここで整理してしまう。

そもそも定義

  • 値渡し(call by value): メソッドの引数に、新たに値のコピーを作って渡す方法のこと。
  • 参照渡し(call by reference): メソッドの引数に、変数そのものの参照を渡す方法のこと。

Javaの場合

  • メソッドへの引数は100%値渡しで渡される。
  • が、Javaのオブジェクトが変数に収納されている時、そこに収納されているのは「そのオブジェクトが収納された場所を示す参照値(reference value)」である
  • よって、オブジェクトを引数として渡すときにはその参照値(reference value)のコピーが渡されている。
  • この結果、「引数に渡したオブジェクトが参照渡しで書き換えられている」かのように勘違いしそうになる。

Goの場合

  • ポインタを引数として渡すことで参照渡しを実現する。
  • Golangの構造体/Arrayは(Javaのオブジェクトとは違って)値型。すなわちその全てのフィールド/要素を収納する場所を確保し、それを構造体を表す変数に収納しているイメージ。
  • よって構造体を値渡しすると、そのフィールドの全てがコピーされる。これを書き換えても元の構造体は書き変わらない。
  • 一方で、map/sliceは(Javaのオブジェクトと同様)参照型。すなわち変数に入っているのは要素のポインタが入った容器であり、各要素にアクセスするにはポインタを辿っているイメージ(参考)。
  • このため、これらを値渡ししたとしても、元のmap/sliceが書き換わってしまう。よって、普通これらをポインタ渡しする意味はなく、普通そうしない(参考)。

補足

  • 参照渡し ≒ ポインタ渡しであるかのように書いたが、そこの細かいところはこちらに詳しい。
  • 値型/参照型の説明は正確ではないかもしれないのであくまでイメージとして捉えてほしい。

参考

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?