Mówisz o mniejszej składni niż strukturze . Tak naprawdę można mieć tylko taką when
instrukcję w systemie, który wykonuje skończoną ilość logiki, a następnie wykonuje when
instrukcje, następnie zapętla się i wykonuje logikę ponownie, kontynuując w nieskończonej pętli.
Na przykład programowanie w systemie Windows jest zazwyczaj „oparte na zdarzeniu”. Subskrybowanie Click
zdarzenia przycisku w zasadzie oznacza „zrób to po kliknięciu”. Jednak pod maską działa pętla przetwarzania wiadomości. System Windows wysyła komunikat do aplikacji, gdy użytkownik kliknie przycisk, a pętla przetwarzania komunikatów w aplikacji uruchamia odpowiednią procedurę obsługi zdarzeń.
Jeśli korzystasz ze zdarzeń, na przykład w C #, możesz to zrobić bez pętli komunikatów, ale ograniczenie polega na tym, że musisz zadeklarować zdarzenie z wyprzedzeniem, więc nie możesz napisać when
instrukcji biblioteki , która będzie obserwować każdy rodzaj stan. Musisz poczekać na określone wydarzenie.
Aby uzyskać takie zachowanie w architekturze Von Neumann, musisz uruchomić jakąś nieskończoną pętlę, która za każdym razem sprawdza wszystkie warunki za pośrednictwem pętli z uruchomionym odpowiednim kodem, jeśli jest to właściwe. Wewnętrznie otrzymujesz dużą listę if
/ then
lub switch
wyciągów. Większość aplikacji komputerowych i programistów internetowych zwymiotowałaby, gdyby zobaczyli taką konstrukcję, więc jest to naprawdę smaczne, jeśli otoczysz ją jakimś cukrem syntaktycznym, takim jak model zdarzeń Windows (nawet jeśli to się dzieje pod maską).
Z drugiej strony, jeśli spojrzysz na dziedzinę oprogramowania wbudowanego, menedżerów w czasie rzeczywistym lub kontrolerów przemysłowych, ten model programowania jest bardzo powszechny. Na przykład, jeśli masz program działający w czasie rzeczywistym, możesz chcieć wyrazić:
outputA = input1 && input2
Kod jest prosty do zrozumienia (ponieważ jest deklaratywny). Aby jednak działało, musisz wykonać go w ciasnej pętli. Ponownie oceniasz za outputA
każdym razem przez pętlę. Wielu programistów stacjonarnych lub internetowych nie spodobałoby się to, ponieważ jest nieefektywne. Dla nich jedyną porą, którą powinieneś ponownie ocenić, outputA
jest czas input1
lub input2
zmiany. Wolą zobaczyć coś, co opisujesz:
when input1 changes
evaluateOutputA()
when input2 changes
evaluateOutputA()
evaluateOutputA()
outputA = input1 && input2
Teraz, jeśli tego właśnie chcesz (a osobiście nie wolę tego pomysłu), a twoim celem jest wydajność, nadal musisz zadać sobie pytanie, co robi procesor pod maską. Oczywiście nadal działa pętla, która za każdym razem porównuje stany wejściowe z poprzednimi stanami wejściowymi i wykonuje odpowiedni kod przy każdej zmianie. Tak naprawdę jest mniej wydajny, trudniejszy do odczytania i trudniejszy w utrzymaniu.
Z drugiej strony, jeśli praca, którą musisz wykonać, gdy input1
zmiany są znaczące, twoja when
klauzula może mieć sens. W sterownikach tego typu instrukcje nazywane są „wykrywaniem zbocza narastającego”. Zapisuje stan input1
ostatniej chwili przez pętlę, tym razem porównuje ją z wartością i wykonuje logikę, jeśli ostatni stan był fałszywy, a ten stan jest prawdziwy.
Jeśli nie masz architektury von Neumanna, gra się zmieni. Na przykład, jeśli programujesz FPGA w VHDL , wtedy kiedy piszesz:
outputA = input1 && input2
(... lub cokolwiek odpowiedniej składni VHDL będzie), a następnie FPGA faktycznie pobiera się w taki sposób, przewodowy input1
i input2
są podłączone do wejścia elementu I, a wyjście z bramki AND jest podłączony do outputA
. Kod jest więc nie tylko łatwy do zrozumienia, ale także wykonywany równolegle z całą inną logiką i jest wydajny.
Gdy mówisz o sterowniku przemysłowym, takim jak PLC lub PAC, zaprogramowanym w jednym z pięciu języków IEC-61131-3, typowym przypadkiem jest taki układ:
- Odczytaj dane wejściowe i zapisz w pamięci
- Uruchom program główny
- Zapisuj wyjścia z pamięci na rzeczywiste wyjścia
- Przejdź do kroku 1
Jest to wbudowane w architekturę systemu, więc oczekuje się, że napiszesz:
outputA = input1 && input2
... i zostanie wykonany w ciągłej pętli.
Istnieją również procedury przerwania w tych maszynach. Są one bardziej jak wsparcie na poziomie sprzętowym dla when
operatora, o którym mówisz. Przerwanie sprzętowe jest sposobem wykonywania kodu na zdarzenie zewnętrzne. Na przykład, gdy karta sieciowa mówi, że czekają na nią dane, procesor zwykle musi natychmiast odczytać te dane lub zabraknie miejsca w buforze. Jednak z uwagi na to, ile razy trzeba złapać prawdziwe przerwanie sprzętowe, wątpię, czy warto podać słowo kluczowe dla tego języka. Będziesz ograniczony do pinów wejściowych procesora i wygląda na to, że chcesz przetestować wewnętrzny stan programu.
Tak więc w tradycyjnym języku (bez ciasnej pętli, która działa nieskończenie), musisz zadać pytanie „kiedy działa kod ewaluacyjny”?
Jeśli napiszesz:
when A do
launchNukes()
... i zakładając A
jest to dowolne wyrażenie boolowskie, skąd wiesz, kiedy ponownie ocenić to wyrażenie? Naiwna implementacja oznaczałaby konieczność ponownej oceny po każdym zapisie w pamięci. Możesz pomyśleć, że możesz to zawęzić, ale rozważ to:
when systemTime > actionTime do
launchNukes()
Zauważ, że systemTime
zawsze się zmienia (za każdym razem, gdy ją czytasz, dostajesz inny numer). Oznacza to, że część warunkowa wszystkich when
klauzul musi być ciągle oceniana. To prawie niemożliwe (i zastanów się przez chwilę, co się stanie, jeśli wyrażenie warunkowe ma skutki uboczne!)
Wniosek
Możesz mieć tylko when
instrukcję (tak jak to opisujesz) w architekturze opartej na nieskończonej pętli, która uruchamia główny program, a następnie wykonuje when
instrukcje, jeśli warunki w tej pętli zmieniły się z false na true. Chociaż ta architektura jest powszechna w urządzeniach wbudowanych i przemysłowych, nie jest powszechna w językach programowania ogólnego przeznaczenia.
select case table1.col1 when 1 then 'Y' else 'N' end as col1_yn from ...
. Ponadto: msdn.microsoft.com/en-us/library/dd233249.aspx Zasadniczo zrobiłbym wyszukiwanie „kiedy” za pomocą wyszukiwania kodu Google.