web-dev-qa-db-ja.com

関数の戻り値の型としての「<-chan」と「chan」の違いは何ですか?

Golang初心者.

機能的に違いはありますか

func randomNumberGenerator() <-chan int {

そして

func randomNumberGenerator() chan int {

私は両方を使用してみましたが、それらは私にとってはうまくいくようです。

前者は、Google IO 2012でのGo同時実行パターンの講演でRob Pike(Goクリエーターの1人)が使用したものを見てきました。また、Goの公式Webサイトでも使用されています。省略できるのに、なぜ2つの余分な文字( "<-")を追加するのですか?ウェブ上で違いを探してみましたが、見つかりませんでした。

33
Abhishek S

どちらも実際に機能します。しかし、1つはより制約になります。 chanキーワードの反対側を指す矢印の付いたフォームは、返されたチャネルがクライアントコードからのみプルできることを意味します。プッシュ不可:プッシュは乱数ジェネレーター機能によって行われます。逆に、矢印がchanを指す3番目のフォームがあります。これにより、チャネルはクライアントに対して書き込み専用になります。

chan   // read-write
<-chan // read only
chan<- // write only

これらの追加された制約により、意図の表現が改善され、型システムが強化されます。読み取り専用チャネルにものを強制しようとすると、コンパイルエラーが発生し、書き込み専用チャネルから読み取ろうとします。これらの制約は戻り値の型で表すことができますが、パラメータシグネチャの一部にすることもできます。のように :

func log(<-chan string) { ...

そこで、署名だけで、log関数がチャネルからデータを消費し、チャネルにデータを送信しないことがわかります。

38
Mathias Dolidon

これは 受信専用チャネル の例です。

オプションの<-演算子は、チャネルの方向、送信または受信を指定します。方向が指定されていない場合、チャネルは双方向です。チャネルは、変換または割り当てによって送信のみまたは受信のみに制限される場合があります。

APIのユーザーに、そのチャネルからのみ受信し、しない送信するように指示すると便利です。そうしないと、問題が発生します。パブリックAPIでチャネルの方向を指定することをお勧めします。参照: チャネルを使用したGo APIの設計原則

11
Ainar-G