52579


go言語の並列処理（並行処理?）を利用して遅延更新のようなことは可能でしょうか？当方goroutine初心者です。

やりたいことは以下です

  * ある関数の中でSampleObjectという構造体を返す 
    * SampleObjectの中身は後の処理で確定するのでそれまで設定しない
    * SampleObjectを作った関数とは全然別の関数、スコープで中身を更新する

擬似コード的に書いてますので間違いあればご指摘ください。

[code]

    // SampleObject内に受信用のchannelを設定して関数の外でSampleObjectの中身を更新する
    func UpdateStructLater() SampleObject {
        return &SampleObject{make(chan, string)}
    }
    
    sObj := UpdateStructLater()
    someSuperProcedure()
    // sObj == "Hello" みたいな
    
[/code]


CC BY-SA 4.0
2019-02-05T10:25:54.183
52566
2019-02-06T02:06:47.710
2019-02-05T10:32:43.177
4715
4715
question
go
Go言語でgoroutineを利用したstructの要素更新


channel そのものと、channel に送信された値とを区別してください。構造体のフィールドに channel を代入しても、その channel
に送信された値がそのフィールドへ代入されるわけではありません。

初期化された構造体の一部を更新したい場合、並列処理は関係なく単にそのフィールドへ後から代入すれば良いです。Go では struct
の初期化時に省略されたフィールドはゼロ値で初期化されることに注意してください。

[code]

    sObj := SampleObject{}
    
    update(&sObj)
    // または
    // sObj.SampleField = newValue()
    // または *SampleObject のメソッドとして定義して
    // sObj.update()
    
[/code]

複数の更新をしなければならず、またそれらを並列的に処理して意味があるのであれば、たとえば sync
パッケージを使って並列的に処理する方法が考えられます。下のコードでは Mutex を使って排他処理させつつ、WaitGroup
を使って全ての更新が終わったことを検知しています。

この処理と同様のことは channel だけでも表現できますが、sync
パッケージを使った方が見やすいかなと個人的には感じます。また、下のコードでは簡単のために Mutex のロック範囲を struct
全体にしていますが、フィールドごとにしても良いですし、依存関係が無いならロックしなくても平気です。

[code]

    type SampleObject struct {
        X int
        Y int
        m sync.RWMutex
    }
    
    // 引数はポインタであることに注意
    func update1(wg *sync.WaitGroup, sObj *SampleObject) {
        defer wg.Done()
    
        // 重い処理
    
        sObj.m.Lock()
        sObj.X = 42
        sObj.m.Unlock()
    }
    
    func update2(wg *sync.WaitGroup, sObj *SampleObject) {
        defer wg.Done()
    
        // 重い処理
    
        sObj.m.Lock()
        sObj.Y = 43
        sObj.m.Unlock()
    }
    
    func main() {
        sObj := SampleObject{}
    
        var wg sync.WaitGroup // 各々の更新が終わったことを確認する用
    
        wg.Add(1)
        go update1(&wg, &sObj)
        wg.Add(1)
        go update2(&wg, &sObj)
    
        wg.Wait() // 全ての更新が終了するまで待つ
    
        // ...その後の処理...
    }
    
[/code]


CC BY-SA 4.0
2019-02-06T02:06:47.710
52579
2019-02-06T02:06:47.710
19110
52566
answer