ты придаёшь слишком много значения мелочам. а каналы в го это частный случай для активного оберона
Sergey Durmanov, [09.11.20 09:19]
допустим, у нас есть такой код на go
Sergey Durmanov, [09.11.20 09:21]
package main
Код: Выделить всё
import "fmt"
func squares(c chan int) {
for i := 0; i <= 9; i++ {
c <- i * i
}
close(c) // close channel
}
func main() {
fmt.Println("main() started")
c := make(chan int)
go squares(c) // start goroutine
// periodic block/unblock of main goroutine until chanel closes
for val := range c {
fmt.Println(val)
}
fmt.Println("main() stopped")
}
Sergey Durmanov, [09.11.20 09:22]
мы сделаем похожее на активном обероне, реализовав некое подобие каналов
Sergey Durmanov, [09.11.20 09:22]
вот наш канал
Sergey Durmanov, [09.11.20 09:22]
module IntegerChannel;
type
T* = object
var data: integer;
var hasData, isClosed: boolean;
procedure & Init*;
begin
data := 0;
hasData := false;
isClosed := false;
end Init;
procedure Send(value: integer) : boolean;
begin { EXCLUSIVE }
await( ~hasData or isClosed );
if ~isClosed then
data := value;
hasData := true;
return true;
end;
trace("send on closed channel");
return false;
end Send;
procedure Receive( var x: integer ): boolean;
begin { EXCLUSIVE }
await( hasData or isClosed );
if hasData then
hasData := false;
x := data;
return true;
end;
trace("receive from a closed channel");
return false;
end Receive;
procedure Close*;
begin { EXCLUSIVE }
isClosed := true;
end Close;
procedure HasData*(): boolean;
begin { EXCLUSIVE }
return ~isClosed or hasData;
end HasData;
end T;
operator "<<"* (c: T; x: integer);
begin
ignore c.Send(x);
end "<<";
operator "<<"* (var x: integer; c: T);
begin
ignore c.Receive(x);
end "<<";
end IntegerChannel.
и программа примерно такая
Sergey Durmanov, [09.11.20 09:24]
Код: Выделить всё
module ChannelTest;
import IntegerChannel;
type
Squares = object
var c: IntegerChannel.T;
procedure & Init( c: IntegerChannel.T );
begin
self.c := c;
end Init;
begin { ACTIVE }
var i: integer;
for i := 0 to 9 do
c << i * i;
end;
c.Close;
end Squares;
procedure main*;
var x: integer;
begin
trace("main started");
var c := new IntegerChannel.T();
ignore new Squares( c );
while c.HasData() do
x << c;
trace(x);
end;
trace("main stopped");
end main;
end ChannelTest.
ChannelTest.main~
System.FreeDownTo ChannelTest~