golangで読み取り専用チャネルを作成する方法

PHPz
リリース: 2023-04-05 10:24:39
オリジナル
671 人が閲覧しました

Golang の Channel は、複数の goroutine 間の通信に使用される特別なデータ型です。シャネルは、送信と受信の 2 つの操作をサポートしています。送信操作はチャネルに値を送信し、受信操作はチャネルから値を受信します。

デフォルトでは、チャネルは読み取りと書き込みが可能です。つまり、どのゴルーチンもチャネルを通じて操作を送受信できます。ただし、場合によっては、特定のゴルーチンを受信のみで送信はしない、または送信のみで受信はしないように制限する必要があります。このとき、読み取り専用チャネルが便利です。

読み取り専用チャネルは、複数のゴルーチンによって同時に読み取ることができますが、書き込むことはできません。これを使用して読み取り専用の共有データ構造を実装し、同時実行性の問題を回避できます。 Go 言語では、読み取り専用チャネルと通常のチャネルの違いがあり、読み取り専用チャネルと書き込み専用チャネルは種類が異なります。

読み取り専用チャネルの作成方法

読み取り専用チャネルは、通常のチャネル タイプの前に <- 記号を追加することで作成できます。たとえば、通常のチャネルがある場合:

ch := make(chan int)
ログイン後にコピー

これを読み取り専用チャネルに変換するには、次のように記述できます:

roCh := <-chan int(ch)
ログイン後にコピー

ここでは、読み取り専用チャネルを作成します。 、その型は <-chan int で、読み取り専用の int 型チャネルです。どちらも int 型データの送信に使用されますが、この読み取り専用チャネルは元の通常のチャネルとは異なる型であることに注意してください。

読み取り専用チャネルの実装

読み取り専用チャネルの場合、データを読み取ることのみが可能であり、データを書き込むことはできません。したがって、読み取り専用チャネルを使用する場合は、次の 2 つの点に注意する必要があります。

  1. 読み取り専用チャネルでは送信操作を実行できません。そうしないと、コンパイル エラーが発生します。
  2. 書き込み可能チャネルを読み取り専用チャネルに変換すると、読み取り専用チャネルと書き込み可能チャネルは同じデータ ブロックを指すため、書き込み可能チャネルで送信操作を実行できます。読み取り専用チャネル経由で受信します。

次は、読み取り専用チャネルの使用を示す簡単な例です:

package main

import "fmt"

func main() {
    ch := make(chan int, 10)
    for i := 0; i < 10; i++ {
        ch <- i
    }

    // 只读channel
    roCh := (<-chan int)(ch)

    // 从只读channel中读取数据
    for x := range roCh {
        fmt.Println("value:", x)
    }
}
ログイン後にコピー

この例では、最初に書き込み可能なチャネルを作成し、それに 10 個の整数を追加します。と書かれていました。次に、この書き込み可能なチャネルを読み取り専用チャネルに変換し、この読み取り専用チャネルを通じてそこからデータを読み取ります。最終的に、プログラムはチャネルに書き込まれたすべてのデータを出力します。

読み取り専用チャネルは共有データ構造に使用されます

読み取り専用チャネルの最も一般的な用途は、同時アクセスの問題を回避するための共有データ構造です。たとえば、読み取り専用チャネルを使用して、データの読み取りのみが可能なスレッドセーフ キューを実装できます。

次は、読み取り専用チャネルを使用してスレッド セーフ キューを実装する方法を示す簡単な例です:

package main

import "fmt"

type Queue struct {
    roCh <-chan interface{}
}

func NewQueue(size int) *Queue {
    ch := make(chan interface{}, size)
    return &Queue{
        roCh: (<-chan interface{})(ch),
    }
}

func (q *Queue) Push(v interface{}) {
    ch := q.roCh.(chan<- interface{})
    ch <- v
}

func (q *Queue) Pop() interface{} {
    return <-q.roCh
}

func main() {
    q := NewQueue(10)
    for i := 0; i < 10; i++ {
        q.Push(i)
    }

    for i := 0; i < 10; i++ {
        fmt.Println(q.Pop())
    }
}
ログイン後にコピー

この例では、Push メソッドが含まれるキューを実装します。 Pop メソッドはキューに要素を追加するために使用され、キュー内の要素をポップアップして返します。キューは読み取り専用チャネルを使用してデータを共有し、同時アクセスの安全性を確保していることに注意してください。

概要

読み取り専用チャネルは Golang の特別なタイプで、特定の goroutine が操作を受信するだけで操作を送信しないように制限するために使用されます。読み取り専用チャネルを使用して読み取り専用共有データ構造を実装し、同時実行の問題を回避できます。読み取り専用チャネルは、通常のチャネルや書き込み可能なチャネルとは異なるタイプです。読み取り専用チャネルを使用する場合は、読み取り専用チャネルで送信操作を実行しないように注意する必要があります。そうしないと、コンパイル エラーが発生します。

以上がgolangで読み取り専用チャネルを作成する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート