チャネルがデータの読み取りのみ可能な場合は、チャネルにデータを書き込むことができないため、そのチャネルは空である必要があります。同様に、データを書き込むだけのチャネルの場合、データを書き込んでも内部のデータを読み取ることができないため、意味がありません。いわゆる一方向チャネルの概念は、実際にはチャネルの使用に対する制限にすぎません。
一方向チャネルの宣言形式
チャネル変数を関数に渡すとき、それを一方向チャネル変数として指定することで、このチャネルにデータを書き込むだけ、またはこのチャネルからのみデータを読み取るなど、関数内でのこのチャネルの操作を制限できます。
一方向チャネル変数の宣言は非常に簡単です。データの書き込みのみが可能なチャネル タイプはchan<-
、データの読み取りのみが可能なチャネル タイプは<-chan
です。形式は次のとおりです。
var チャネルインスタンス chan<- 要素タイプ
var チャネルインスタンス <-chan 要素タイプ
- 要素タイプ: チャネルに含まれる要素のタイプ。
- チャネルインスタンス: 宣言されたチャネル変数。
一方向チャネルの使用例
サンプルコードは次のとおりです。
ch := make(chan int)
// データの書き込みのみ可能なチャネルタイプを宣言し、chに値を設定する
var chSendOnly chan<- int = ch
// データの読み取りのみ可能なチャネルタイプを宣言し、chに値を設定する
var chRecvOnly <-chan int = ch
上記の例では、chSendOnly はデータの書き込みのみを行うことができ、データを読み取ろうとすると、次のエラーが表示されます。
invalid operation: <-chSendOnly (receive from send-only type chan<- int)
同様に、chRecvOnly はデータを書き込むことができません。
もちろん、make を使用してチャネルを作成する場合、書き込み専用または読み取り専用のチャネルを作成することもできます。
ch := make(<-chan int)
var chReadOnly <-chan int = ch
<-chReadOnly
上記のコードはコンパイルされ、正しく実行されます。ただし、データの書き込みができず、読み取りだけが可能なチャネルは意味がありません。
一方向チャネルインタイムパッケージ
time パッケージ内のタイマーはタイマー インスタンスを返します。コードは次のとおりです。
timer := time.NewTimer(time.Second)
タイマーの Timer タイプは次のように定義されます。
type Timer struct {
C <-chan Time
r runtimeTimer
}
2 行目のチャネル C のタイプは、読み取り専用の一方向チャネルです。ここでチャネル方向の制約がない場合、外部データがチャネルに書き込まれると、タイマーが使用される他の場所のロジックに混乱が生じます。
したがって、単方向チャネルはコード インターフェイスの厳密化に役立ちます。
チャネルを閉じるのは非常に簡単で、Go 言語の組み込み close() 関数を使用するだけです。
close(ch)
チャネルを閉じる方法を紹介した後、もう 1 つの質問があります。チャネルが閉じられたかどうかをどのように判断するかです。読み取り時に複数の戻り値を使用できます。
x, ok := <-ch
この使用法は、マップのキーによって値を取得するプロセスに似ています。2 番目の bool 戻り値だけを見る必要があります。戻り値が false の場合は、ch が閉じられていることを意味します。