LoginSignup
1
0

【Go言語学習】引数の参照渡しについて

Last updated at Posted at 2024-05-11

以下のコードは、セマフォを使って(あんま意味ないけど)、同時実行数を制限しているコードで遊んでいたのですが、do関数の引数について疑問が発生したのでメモ。

package main

import (
	"context"
	"fmt"
	"log"
	"time"

	"golang.org/x/sync/semaphore"
)

func main() {
	sem := semaphore.NewWeighted(5)

	go do(sem, func() { time.Sleep(1 * time.Second) }, 1)
	go do(sem, func() { time.Sleep(1 * time.Second) }, 2)
	go do(sem, func() { time.Sleep(1 * time.Second) }, 3)
	go do(sem, func() { time.Sleep(1 * time.Second) }, 4)
	go do(sem, func() { time.Sleep(1 * time.Second) }, 5)
	// 	go do(sem, func() { time.Sleep(1 * time.Second) }, 6) エラー

	time.Sleep(6 * time.Second)
	fmt.Println("最高!")
}

func do(sem *semaphore.Weighted, f func(), w int64) { // ここの引数について
	if err := sem.Acquire(context.Background(), w); err != nil {
		log.Println(err)
		return
	}
	defer sem.Release(w)

	switch w {
	case 1:
		log.Printf("It will definitely come true!")
	case 2:
		log.Printf("That works!")
	case 3:
		log.Printf("I did it!")
	case 4:
		log.Printf("Thank you for this world!")
	case 5:
		log.Printf("Make the world better!")
	case 6:
		log.Printf("Do not lose!")
	default:
		log.Printf("How happy I am!")
	}

	f()
}

https://github.com/kabasunny/GoPractice/tree/main/semaphore_fanc
このケースでは、func do(sem *semaphore.Weighted, f func(), w int64)となっていて、セマフォは見てわかるように明示的にポインタで受け取るが、関数型の引数は暗黙的に参照で受け取る。

あとついでに、分かったことメモ
・インターフェースを直に実装した関数は作れない
・インターフェースは変数を持てない
・関数は、自身の関数型のみで共有する変数を持てない
・データ型の引数は値(アドレスポインタの値)のコピー渡しが基本で、参照渡しは無い(ただし、スライス、マップ、チャネルなどの一部のデータ型は、内部的には参照型として振る舞うだとぅ!?)
・関数型を引数として渡す場合は参照の値渡しとなる

1
0
10

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
1
0