Git dilinin, birden çok kanalı yoklamak ve ilk olarak hangi kanalın boş olmadığına bağlı olarak belirli bir eylemi gerçekleştirmek için kullanılabilecek bir select
bildirimi vardır.Go'nun Haskell STM kanalları için select deyiminin karşılığı nasıl uygulanır?
E.g. chanA
, chanB
veya chanC
ya olmayan boşalana kadar
select {
case a := <- chanA:
foo(a)
case b := <- chanB:
baz(b)
case c := <- chanC:
bar(c)
}
Bu da örnek chanB
olmayan boş için, eğer chanB
okuyacak, bekleyecek ve b
sonucu depolamak, sonra baz(b)
diyoruz. default:
maddesinin eklenmesi de mümkündür, yani select
ifadesi kanallarda beklemez ve bunun yerine tüm kanallar boşsa default
tümcesini ne yaparsa yapar.
STM TChan
s Haskell'de bunun gibi bir şeyin uygulanmasının en iyi yolu ne olurdu? Bir if-else zinciri tarafından naif olarak yapılabilir: her bir isEmptyChan
no'lu değişkenin olup olmadığını kontrol edin ve eğer boş değilse, ondan okuma yapın ve uygun işlevi çağırın, veya tüm kanallar boşsa retry
'u arayın. Bunu yapmak için daha zarif/deyimsel bir yol olup olmadığını merak ediyordum?
Go'nun select
bildiriminin kendi durumlarında gönderme ifadelerini de içerebileceğini ve yalnızca kanalı boşsa bir gönderim deyimini tamamlayabileceğini unutmayın. Bu işlevsellik de çoğaltılabiliyor olsaydı harika olurdu, ancak bunun için şık bir yol olup olmayacağından emin değilim.
Sadece biraz ilgili ama bir şey şu anda fark ve bunu yayınlamak için nereye emin değilim:
"uygulaması biri kadar iplik engelleyebilir: retry
açıklama alanına Control.Monad.STM sayfasında bir yazım hatası var Okumak TVars, udpated olmuştur. "
Control.Concurrent.Async 'den as. –
Gitmenin, mevcut ilk işlemi gerçekleştirmediğini, ancak rastgele seçilen herhangi birini kullanabileceğini unutmayın. Özellikle kanalları açmaz, çünkü seçim yolunda daha sonra veya şanssız olarak tanımlanırlar. – Dustin
Bu, Go'nun 'select' seçeneğinden tamamen farklıdır. Go'daki kanallar, "TChan" ın aksine (aslında onları yararlı kılar) ve "select" komutları gönderim işlemleriyle kullanılabilir. – rightfold