К моему явному восторгу я обнаружил, что D достиг прогресса и теперь фактически работает на Windows 64 бит. У него даже есть интеграция с Visual Studio, которая, кажется, работает, насколько я могу видеть после нескольких часов игры с моей новой игрушкой.Письменные функции, соответствующие шаблонам определенных функций прототипов
Таким образом, очевидно, что я только начал играть с D как язык, и я кровавый новичок в D.
В коде ниже моей целью было определить прототипы функций в шаблоне, а затем писать функции как суб -функции main(), которые соответствуют этим прототипам. Но компилятор жалуется, и прямо сейчас я не могу понять, как правильно это сделать (возможно, простая проблема синтаксиса).
Ошибки компилятора я получаю:
main.d(90): Error: function main.Actor!(int, int).Worker (Duration timeout, bool function(int) timeoutHandler, bool function(int, int) messageHandler, int context) is not callable using argument types()
main.d(90): Error: function main.main.W1OnTimeout (int context) is not callable using argument types()
main.d(90): Error: function main.main.W1OnMessage (int context, int message) is not callable using argument types()
Building Debug\ConsoleApp1.exe failed!
import std.stdio;
import core.time;
import std.socket;
import std.concurrency;
import core.thread;
enum SystemMessage
{
Shutdown,
Terminate,
Ping,
Enable,
Disable
}
template Actor(C,M)
{
// TimeoutHandler implementations always return true
// unless the worker shall terminate.
alias TimeoutHandler = bool function(C);
// MessageHandler implementations always return true
// unless the worker shall terminate.
alias MessageHandler = bool function(C,M);
void
Worker
(Duration timeout
, TimeoutHandler timeoutHandler
, MessageHandler messageHandler
, C context
)
{
bool running = true;
bool enabled = true;
while(running)
{
if(true == std.concurrency.receiveTimeout
(timeout,
(M message)
{
if(enabled)
{
if(!messageHandler(context,message))
{
running = false;
}
}
},
(SystemMessage message)
{
switch(message)
{
case SystemMessage.Shutdown: running = false; break;
case SystemMessage.Terminate: running = false; break;
case SystemMessage.Enable: enabled = true; break;
case SystemMessage.Disable: enabled = false; break;
case SystemMessage.Ping: /* TODO: supervisor... */; break;
default: break;
}
}
))
{
}
else
{
if(!timeoutHandler(context))
{
running = false;
}
}
}
}
}
alias IntIntActor = Actor!(int,int);
int main(string[] argv)
{
// The signatures of the next 2 functions conform to the function
// declarations, given in Actor template (IntIntActor).
// How to write them so it works?
bool W1OnTimeout(int context)
{
writeln("W1OnTimeout()");
return true;
}
bool W1OnMessage(int context,int message)
{
writefln("W1OnMessage: context = %d, message = %d", context, message);
return true;
}
// Do I need some special syntax here? Like e.g. &W1OnTimeout ? Or a cast?
auto w1 = spawn(IntIntActor.Worker,1000.msecs,W1OnTimeout,W1OnMessage,1);
for(int i = 0; i < 10; i++)
{
send(w1,i);
}
Thread.sleep(5000.msecs);
send(w1,SystemMessage.Shutdown);
thread_joinAll();
return 0;
}
Спасибо за вашу помощь, заранее!
Создание их статических и добавление & все еще производит 1 ошибку (то же самое, что и те, что я получил раньше). – BitTickler
Woops, я упомянул '& W1OnTimeout' дважды и пропустил' & IntIntActor.Worker'. Все трое нуждаются в '&'. Отредактировал ответ. – user5282325
Окей - для рабочего был скупой - так как основное внимание уделялось двум не-лямбда-функциям :) Как это будет работать для делегатов (где я мог бы пройти в закрытии)? – BitTickler