Help us understand the problem. What is going on with this article?

Goでxxxのポインタを取っているプログラムはだいたい全部間違っている

More than 5 years have passed since last update.

Goで、文字列、インターフェイス、チャネル、マップ、スライスのポインタを取っているプログラムは、書いた本人がきちんと自分がなにをしているのか理解しているのでなければ、ほぼ確実に間違っているといっていい。

Goではある種の型の値はそもそもポインタのようなものである。上記の型はどれも任意の大きさになり得るが、大きくなりうる実体のデータはヒープに確保されていて、値そのものが持っているのはそのヒープ上への値へのただのポインタ+多少の付随的なデータにすぎない。こういった値を値渡しではなくポインタ渡しする必要はない。ポインタのデリファレンスのほうがポインタのコピーより高くつくし、余計な混乱を引き起こすだけだからだ。もしこういう値をポインタ渡ししているとしたら、そのコードはなにか深い意味があるのではなく、それを書いた人が大きな値がコピーされると勘違いしていて書いた可能性のほうがずっと高い。

文字列は2ワードの値で、文字列実体の先頭へのポインタと文字列の長さ(バイト長)からできている。どちらのワードも書き換えることはできない。Goでは文字列は不変だから、コピーを渡そうがそれへのポインタを渡そうができることに違いはなく、文字列を渡すときはポインタのポインタを渡す(文字列へのポインタを渡す)より素直に文字列(実体へのポインタ)を値渡しするほうがよい。

インターフェイスも2ワードの値で、実際の値の型へのポインタと実際の値へのポインタからできている。インターフェイスを書き換えることも普通はできない(インターフェイス型の値が指している先をすげ替えたりインターフェイスが指している値の型を変更したりすることは普通はありえない)。従って値渡しするほうが素直だ。

チャネル、マップも同じだ。

スライスもやはり同じである。スライスは3ワードの値で、実体のデータへのポインタと、配列のキャパシティ、それから長さの3つの値からできている。スライスは要は配列へのポインタなので、これもわざわざポインタへのポインタを渡すのではなく値渡しするほうが普通だ。

というわけで、こういう型の値は正当な理由なくポインタをとったりしないことに注意されたい。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした