简单翻译go到d
go的多任务好,但不完美.语法简单,强大抽象.如果你腻了.试试d.
d支持纤程,但仅单线程.但有库jin.go
.
原文在此
unittest
{
import core.time;
import std.range;
import jin.go;
__gshared static string[] log;
static void saying(string message){//必须是静
foreach( _ ; 3.iota ){
sleep( 100.msecs);
log ~= message;
}
}//没访问本地变量
go!saying( "hello" );
sleep( 50.msecs );
saying( "world" );
log.assertEq([ "hello" , "world" , "hello" , "world" , "hello" , "world" ]);
}
unittest{//无等待栈
import jin.go;
auto numbers = new Channel!int(2);
numbers.next = 1;
numbers.next = 2;//next不如<-方便
numbers.next.assertEq( 1 );
numbers.next.assertEq( 2 );
//手动监控,读写不能超过一个
//通道大小512字节
}
unittest
{
import std.algorithm;
import std.range;
import jin.go;
static auto summing( Channel!int sums , const int[] numbers ) {
sums.next = numbers.sum;//标准算法,要实现区间接口
}
immutable int[] numbers = [ 7 , 2 , 8 , -9 , 4 , 0 ];
Inputs!int sums;//这个,从每个注册的非空频道读
go!summing(sums.make(1),numbers[0 .. $/2 ] );
go!summing(sums.make(1),numbers[$/2 .. $ ] );//不变数组,并行
auto res = sums.take(2).array;//取.
( res ~ res.sum ).assertEq([ 17 , -5 , 12 ]);
}//go.d非阻塞.你必须建一个通信通道,
//为了方便,建立<平衡器输入和输出>.
unittest
{
import std.range;
import jin.go;
static auto fibonacci( Channel!int numbers , int count )
{
auto range = recurrence!q{ a[n-1] + a[n-2] }( 0 , 1 ).take( count );
foreach( x ; range ) numbers.next = x;
numbers.close();
}
auto numbers = new Channel!int(10);
go!fibonacci( numbers , numbers.size );
numbers.array.assertEq([ 0 , 1 , 1 , 2 , 3 , 5 , 8 , 13 , 21 , 34 ]);
}
//化简为:
unittest
{
import std.range;
import jin.go;
static auto fibonacci( int limit ){
return recurrence!q{ a[n-1] + a[n-2] }( 0 , 1 ).take( limit );
}//recurrence->再现
fibonacci( 10 ).array.assertEq([ 0 , 1 , 1 , 2 , 3 , 5 , 8 , 13 , 21 , 34 ]);
go!fibonacci( 10 ).array.assertEq([ 0 , 1 , 1 , 2 , 3 , 5 , 8 , 13 , 21 , 34 ]);
}
unittest
{
import std.range;
import jin.go;
__gshared int[] log;
static auto fibonacci( Channel!int numbers , Channel!bool control )
{
auto range = recurrence!q{ a[n-1] + a[n-2] }( 0 , 1 );
while( !control.closed )
{
if( numbers.needed ) numbers.next = range.next;
yield;
}
log ~= -1;
numbers.close();
}
static void print( Channel!bool control , Channel!int numbers )
{
foreach( i ; 10.iota ) log ~= numbers.next;
control.close();
}
auto numbers = new Channel!int(1);
auto control = new Channel!bool(1);
go!print( control , numbers );
go!fibonacci( numbers , control );
while( !control.empty || !numbers.empty ) yield;
log.assertEq([ 0 , 1 , 1 , 2 , 3 , 5 , 8 , 13 , 21 , 34 , -1 ]);
}
unittest
{
import core.time;
import jin.go;
static auto after( Channel!bool channel , Duration dur )
{
sleep( dur );
if( !channel.closed ) channel.next = true;
}
static auto tick( Channel!bool channel , Duration dur )
{
while( !channel.closed ) after( channel , dur );
}
auto ticks = go!tick( 101.msecs );
auto booms = go!after( 501.msecs );
string log;
while( booms.clear )
{
while( !ticks.clear ) {
log ~= "tick";
ticks.popFront;
}
log ~= ".";
sleep( 51.msecs );
}
log ~= "BOOM!";
log.assertEq( "..tick..tick..tick..tick..BOOM!" );
}//很多看不懂了.
unittest
{
import core.atomic;
import core.time;
import std.range;
import std.typecons;
import jin.go;
synchronized class SafeCounter
{//同步类告诉你,建了个锁
private int[string] store;
void inc( string key )
{
++ store[key];
}
auto opIndex( string key )
{
return store[ key ];
}
void opIndexUnary( string op = "++" )( string key )
{
this.inc( key );
}
}//危险的是`模板方法不在互斥锁内`.
//实现了个`inc`.实现难看,但好用
static counter = new shared SafeCounter;
//可安全传递,可直接在不同的流中使用
static void working( int i )
{
++ counter["somekey"];
}
foreach( i ; 1000.iota ) {
go!working( i );
}
sleep( 1.seconds );
counter["somekey"].assertEq( 1000 );
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现