カテゴリ: Go言語 更新日: 2026/02/13

Go言語の関数パラメータ!値渡しと参照渡しの違いを理解しよう

Go言語の関数パラメータ!値渡しと参照渡しの違いを理解しよう
Go言語の関数パラメータ!値渡しと参照渡しの違いを理解しよう

先生と生徒の会話形式で理解しよう

生徒

「Go言語で関数に値を渡すときって、どういう仕組みなんですか?」

先生

「いい質問ですね。Go言語ではすべて値渡しですが、ポインタを使うことで元の値を変更できます。」

生徒

「えっ、参照渡しはないんですか?」

先生

「厳密にはありません。ただし、ポインタを使うと参照渡しのような挙動になります。順番に解説しましょう。」

1. Go言語の関数とは?

1. Go言語の関数とは?
1. Go言語の関数とは?

まず、関数とは「何かの処理をまとめて、名前をつけて呼び出せるようにしたもの」です。例えば、「足し算をする関数」を作れば、好きなときにその計算を呼び出して使うことができます。

Go言語では、関数は次のように書きます。


func 足し算(a int, b int) int {
    return a + b
}

funcは関数を定義するキーワード、a intb intは引数(関数に渡すデータ)、intは戻り値の型を表します。

2. 値渡しとは?

2. 値渡しとは?
2. 値渡しとは?

Go言語では、関数に変数を渡すとき、基本的には値渡し(英語でpass by value)になります。これは「変数の中身のコピーを渡す」という意味です。

つまり、関数の中で変数の値を変更しても、元の変数には影響がありません。

たとえば、次のようなコードです。


func 変更する(x int) {
    x = 100
}

func main() {
    a := 10
    変更する(a)
    fmt.Println(a)
}

このとき、出力結果はどうなると思いますか?


10

関数内でxを100に変えても、aには影響がないのです。なぜなら、aのコピー(x)を渡しているからです。

3. 参照渡しのように見える挙動とは?

3. 参照渡しのように見える挙動とは?
3. 参照渡しのように見える挙動とは?

Go言語では、すべての引数は値渡しです。これはポインタを使った場合でも変わりません。

ただし、ポインタを引数として渡すことで、「元のデータを変更しているように見える」挙動を実現できます。

ポインタとは「変数のアドレスを格納した値」です。つまり、関数にはアドレスのコピーが渡されています。


func 変更する(x *int) {
    *x = 100
}

func main() {
    a := 10
    変更する(&a)
    fmt.Println(a)
}

出力結果は次のとおりです。


100

&aで変数aのアドレスを渡し、*xでそのアドレスが指す値を書き換えています。そのため、結果としてaの値が変更されます。

Go言語を基礎からスッキリ学びたい人や、 文法だけでなく「実用的な使い方」まで押さえたい人には、 定番の入門書がこちらです。

基礎からわかるGo言語をAmazonで見る

※ Amazon広告リンク

4. 値渡しとポインタ引数の違いをイメージで理解しよう

4. 値渡しとポインタ引数の違いをイメージで理解しよう
4. 値渡しとポインタ引数の違いをイメージで理解しよう

値渡しとポインタを使った引数の違いを、日常の例で考えてみましょう。

友達に「メニュー表のコピー」を渡す場合、友達が何を書き加えても、あなたの手元のメニュー表は変わりません。これは値渡しです。

一方、「メニュー表が置いてある場所の住所」を教えた場合、友達がその場所にあるメニュー表を書き換えると、あなたの手元の内容も変わります。

Go言語のポインタは、この「住所(アドレス)を渡す」イメージに近い仕組みです。

5. ポインタの使い方をもう少し深く

5. ポインタの使い方をもう少し深く
5. ポインタの使い方をもう少し深く

Go言語では、ポインタ(アドレス)を引数として渡すことで、関数の中から呼び出し元の値を更新できます。なお、ポインタを渡す場合でも、関数に渡っているのは「アドレスという値のコピー」です。


func ポインタの例(x *int) {
    *x = *x + 1
}

*xは「xが指している場所の中身」という意味です。*x = *x + 1と書けば、中身の値を1増やすことができます。

そして、呼び出し時には&変数名を使います。


num := 5
ポインタの例(&num)
fmt.Println(num) // 結果は6

6. 値渡しとポインタ引数の使い分け

6. 値渡しとポインタ引数の使い分け
6. 値渡しとポインタ引数の使い分け

Go言語では、基本的に値渡しを使う設計が推奨されています。

ただし、次のような場合にはポインタを引数として渡すことがあります。

  • 関数内で値を変更し、その結果を呼び出し元に反映させたい場合
  • 大きな構造体をコピーせず、効率的に処理したい場合

ポインタを使うと副作用が発生しやすくなるため、「本当に変更が必要か」を意識して設計することが重要です。

7. 関数の引数での注意点

7. 関数の引数での注意点
7. 関数の引数での注意点

関数に渡すときにポインタを使うと、データを意図せず変更してしまうこともあります。初心者のうちは「どの関数がデータを変更するか」に注意しましょう。

ポインタを使う=関数が元の変数を変える可能性がある、ということを意識しておくと良いです。

まとめ

まとめ
まとめ

Go言語の関数パラメータと値渡しの基本を振り返る

この記事では、Go言語における関数の引数の仕組みについて、値渡しと参照渡しの違いを軸に解説してきました。Go言語で関数を定義するとき、引数に渡される値は、基本的にすべて値渡しになります。これは、数値型や文字列型といった基本的な型だけでなく、ポインタを使った場合でも同じ考え方です。関数を呼び出すとき、呼び出し元の変数そのものが渡されるのではなく、変数の値、あるいはアドレスという値のコピーが渡される点が重要です。

値渡しの仕組みを正しく理解しておくことで、「関数の中で値を変更したのに、なぜ外側の変数は変わらないのか」といった疑問を自然に説明できるようになります。Go言語の関数設計では、この値渡しの性質を前提として、安全で予測しやすいコードを書くことが推奨されています。

ポインタを使った引数と参照的な挙動

一方で、Go言語ではポインタを引数として渡すことで、参照渡しのように見える挙動を実現できます。ポインタを使うと、関数の中から呼び出し元の変数が保持している値を書き換えることが可能になります。ただし、この場合でも、関数に渡っているのは「変数そのもの」ではなく、「変数のアドレスという値」である点は変わりません。

この考え方を理解せずにポインタを使ってしまうと、意図しない副作用が発生しやすくなります。特に、Go言語での関数設計やコードレビューでは、「この関数は値を変更するのか」「読み取り専用なのか」を意識することが重要になります。

まとめとして確認しておきたいサンプルプログラム

最後に、値渡しとポインタ引数の違いをあらためて確認できる簡単なサンプルを見てみましょう。Go言語で関数を使うとき、どのような書き方をすると値が変わり、どのような場合に変わらないのかを意識することが大切です。


func 値渡しの例(x int) {
    x = x + 10
}

func ポインタ引数の例(x *int) {
    *x = *x + 10
}

func main() {
    a := 5
    値渡しの例(a)
    fmt.Println(a)

    ポインタ引数の例(&a)
    fmt.Println(a)
}

このプログラムでは、最初の関数呼び出しでは値渡しのため変数の値は変わらず、次のポインタを使った関数呼び出しで初めて値が更新されます。この違いを理解しておくことで、Go言語の関数と引数の挙動をより深く理解できるようになります。

先生と生徒の振り返り会話

生徒

「Go言語って、参照渡しがあると思っていましたけど、実際には全部値渡しなんですね。ポインタも値として渡されていると聞いて、だいぶ整理できました。」

先生

「その理解で大丈夫です。Go言語では、関数に渡るものは必ず値です。ただし、その値がアドレスの場合、結果として元の変数が変更される、という仕組みですね。」

生徒

「だから、関数の引数にポインタがあるときは、この関数は値を書き換える可能性がある、と意識したほうがいいんですね。」

先生

「その通りです。値渡しとポインタ引数の違いを意識することで、Go言語らしい読みやすく安全なコードが書けるようになりますよ。」

この記事を読んだ人からの質問

この記事を読んだ人からの質問
この記事を読んだ人からの質問

プログラミング初心者からのよくある疑問/質問を解決します

Go言語の関数とは何ですか?プログラミング初心者でも理解できるように教えてください

Go言語の関数とは、特定の処理をひとまとめにして名前を付けた仕組みです。関数を使うことで、同じ処理を何度も書かずに呼び出すことができ、プログラム全体が読みやすくなります。Go言語では関数に引数を渡したり、戻り値を受け取ったりすることで、柔軟な処理を実現できます。

Go言語で関数に渡す引数とは何ですか?役割を知りたいです

引数とは、関数に処理してほしいデータを渡すための仕組みです。Go言語では関数の定義時に引数の型を明確に指定します。これにより、関数の中でどのようなデータを扱うのかが分かりやすくなり、型安全なプログラムを書くことができます。
カテゴリの一覧へ
新着記事
New1
Go言語
Go言語の短絡評価(ショートサーキット)を使った条件式の工夫をやさしく解説!初心者でも理解できる基本知識
New2
Go言語
Go言語の構造体の初期化パターンとコンストラクタ的関数の書き方を徹底解説!初心者でもわかる基本と実用例
New3
Kotlin
Kotlinの例外処理とキャンセルの連携を完全ガイド!初心者でもわかるCoroutineExceptionHandlerの使い方
New4
Go言語
Go言語のクロージャとは?関数内関数の活用例と仕組み
人気記事
No.1
Java&Spring記事人気No1
Kotlin
KotlinのChannelでデータをやり取りする方法を完全ガイド!初心者にもわかる非同期通信の基本
No.2
Java&Spring記事人気No2
Go言語
Go言語でのDB接続情報を環境変数で管理する方法|初心者でも安全に設定
No.3
Java&Spring記事人気No3
Kotlin
Android Studioのインストール手順と初期設定を初心者向けに完全解説!
No.4
Java&Spring記事人気No4
Kotlin
Kotlinのビルド設定エラーと解決法まとめ!初心者向けGradleトラブル対処ガイド
No.5
Java&Spring記事人気No5
Kotlin
Gradleファイル(build.gradle.kts)の書き方と役割をやさしく解説!Kotlin初心者向け完全ガイド
No.6
Java&Spring記事人気No6
Kotlin
Kotlinでテキスト表示・編集!初心者でもわかるTextViewとEditTextの使い方
No.7
Java&Spring記事人気No7
Go言語
Go言語のgo.modファイル完全ガイド!初心者でもわかる仕組みと書き方
No.8
Java&Spring記事人気No8
Swift
Swift Playgroundの使い方を完全解説!初心者に最適な学習環境の始め方

💻 作業効率アップに

ノートPCを縦置きしてデスクを広く。
省スペースで片づく定番スタンド

UGREEN 縦型スタンドをAmazonで見る

※ Amazon広告リンク