2017-06-02 52 views
2

當傳遞通道的功能,我知道你可以指定信道可以使用該通道的方向;例如,Golang道:傳遞給函數的時候能不能定向?

func MyFunc(ch chan<- string) { 
    ch <- "Hello" 
} 

「CH」只能通過MYFUNC用於發送字符串至接收器別處和MYFUNC不能監聽來自CH消息。

要簡化信道的動態數在一定數夠程的,我創建包含信道的結構。

type ChanStruct struct { 
    chMessages chan string 
} 

然後我實例化一個結構:

var slcChanStruct []ChanStruct 
for a:= 0; a <=2; a++ { 
    var tmpChanStruct ChanStruct 
    tmpChanStruct.chMessages = make(chan string) 
    slcChanStruct = append(slcChanStruct, tmpChanStruct) 
} 

現在我有3個結構我可以單獨通過測距以上結構的切片的信道的讀/寫。但是,當我把他們關到夠程:

for a:=0; a <=2; a++{ 
    go SomeFunc(slcChanStruct[a]) 
} 

...有沒有辦法通過指定夠程只能,例如,發送郵件使用ChanStruct.ch渠道增加一點安全的?

注意我這樣做的原因是,如果我不知道有多少渠道,我需要爲一組並行的進程(進程的數目作爲命令行參數傳遞),使用信道的結構意味着我可以創建一個可以傳遞給任意數量goroutine的片段,並通過遍歷它們來單獨直接訪問它們;之前,如果我想單獨從多個goroutines中讀取數據,我不得不創建一定數量的頻道。我想通過指定進程只能使用一個通道以一定的方式,就像我使用單獨的通道(單個通道的意思是我可以做這樣的事情,告訴特定的goroutine沒有其它夠程攔截它退出時可能添加一些安全這個)。如果我不能使用結構體中的通道爲函數添加方向性,有沒有更習慣的方法來做到這一點?

回答

1

論@阿德里安的建議,如果你要保證在通道上的單向通信,你總是可以使用匿名函數頂部:

for a:=0; a <=2; a++{ 
    go func f(ch <-string) { 
    SomeFunc(ch) 
    }(slcChanStruct[a].chMessages) 
} 

請注意,您必須通過通道到SomeFunc而不是結構。

如果你仍然想將頻道上執行兩個雙向溝通,你可以重新通道分配到一個定向類型:

type ChanStruct struct { 
    chMessages chan string 
} 

type ChanStructRecv struct { 
    chMessages <-chan string 
} 

// Update SomeFunc type: 

func SomeFunc(s ChanStructRecv) { 
    // ... 
} 

最後,循環可以類似地修飾:

for a:=0; a <=2; a++{ 
    go func f(s ChanStruct) { 
    var sr ChanStructRecv 
    sr.chMessages = s.chMessages 
    SomeFunc(sr) 
    }(slcChanStruct[a]) 
} 
0

一對夫婦的方式,根據您的具體情況:

  • 傳遞渠道,而不是結構,使信道參數定向爲你的第一個例子
  • 不要直接暴露通道,只露出一個struct的方法來寫它(如果沒有方法從中讀取數據,這是有效的定向)
  • 充分利用通道結構體成員定向:

例如

type myStruct struct { 
    c chan <- bool 
} 
+0

感謝您的迴應!我曾考慮過第三個例子,但是如果我使結構成員具有方向性,我將如何從接收方讀取它?這不會使它變得不可能嗎? –

+0

接收器將不得不保留自己的通道副本,該通道不是定向通道,或者是隻接收通道,就像您將原始示例直接將定向通道直接傳遞給該功能一樣。 – Adrian

相關問題