D 分解代码,保持可读性,让生活更美好:)
我刚刚开始学习D编程语言,并愉快地玩委托和函数关键字。我正试图实现(仅针对我自己的学习过程)twisted中著名的延迟类(用Python编写) 我只是想知道是否有一些技巧可以排除这种代码:D 分解代码,保持可读性,让生活更美好:),d,D,我刚刚开始学习D编程语言,并愉快地玩委托和函数关键字。我正试图实现(仅针对我自己的学习过程)twisted中著名的延迟类(用Python编写) 我只是想知道是否有一些技巧可以排除这种代码: class Deferred(ResultType) { alias ResultType delegate(ResultType) CallbackType; private CallbackType[2] _callbacks[]; private bool _running;
class Deferred(ResultType)
{
alias ResultType delegate(ResultType) CallbackType;
private CallbackType[2] _callbacks[];
private bool _running;
private uint _paused;
void addCallback(CallbackType cb)
{
this._callbacks ~= [cb, cast(CallbackType) null];
}
void addCallback(void function() f)
{
this.addCallback(
(ResultType res) { f(); return res; }
);
}
void addCallback(void function(ResultType) f)
{
this.addCallback(
(ResultType res) { f(res); return res; }
);
}
void addCallback(ResultType function() f)
{
this.addCallback(
(ResultType res) { return f(); }
);
}
void addCallback(ResultType function(ResultType) f)
{
this.addCallback(
(ResultType res) { return f(res); }
);
}
}
目标是允许用户不传递CallbackType
委托,而是传递一些函数,无论是否使用正确的参数/返回类型。
我是不是遗漏了一些要点
[编辑]:根据的建议,答案可能是这样的:
class Deferred(ResultType)
{
alias ResultType delegate(Deferred, ResultType) CallbackType;
private CallbackType[2] _callbacks[];
void addCallback(T)(T cb)
{
this._callbacks ~= [this._makeConvenient(cb), cast(CallbackType) null];
}
private CallbackType _makeConvenient(T)(T f)
{
alias traits.ReturnType!(f) ReturnType;
alias traits.ParameterTypeTuple!(f) Params;
return (Deferred d, ResultType res)
{
ReturnType wrapper()
{
static if (Params.length == 2)
{
static if (is(Params[0] == Deferred!(ResultType)) && is(Params[1] == ResultType))
return f(this, res);
else
static assert(false, "Cannot wrap given callback: Wrong arguments types");
}
else static if (Params.length == 1)
{
static if (is(Params[0] == Deferred!(ResultType)))
return f(this);
else static if (is(Params[0] == ResultType))
return f(res);
else
static assert(false, "Cannot wrap given callback: Wrong argument type");
}
else static if (Params.length == 0)
return f();
else
static assert(false, "Cannot wrap given callback: Wrong argument number");
}
static if (is(ReturnType == void)) { wrapper(); return res; }
else static if (is(ReturnType == ResultType)) { return wrapper(); }
else static assert(false, "Cannot wrap given callback: Wrong return type");
};
}
}
我这样做对吗?是否存在明显的性能问题 这应该可以做到:
class Deferred(ResultType)
{
alias ResultType delegate(ResultType) CallbackType;
private CallbackType[2] _callbacks[];
private bool _running;
private uint _paused;
void addCallback(CallbackType cb)
{
this._callbacks ~= [cb, cast(CallbackType) null];
}
void addCallback(TFn)(TFn f) //Put template restrictions here if you want
{
this.addCallback((ResultType res)
{
static if (is(typeof(f(res)) == void)) { f(res); return res; }
else static if (is(typeof(f()) == void)) { f(); return res; }
else static if (is(typeof(f(res) == ResultType))) { return f(res); }
else { return f(); }
});
}
}
虽然没有多大好转,但我想没关系。非常感谢!尝试
Is(typeof(f())==void)
是知道f
是否实际接受参数的更好方法吗?@Raphael:“正确”的方法是检查的结果,但这一个更短,所以我使用它。如果您需要更多详细信息,请使用该选项。我使用“更好的方式”编辑了我的第一篇文章:)事实上,我看到表达式是(typeof(f(res)=ResultType)
检查类型是否相等,而是(typeof(f(res)):ResultType)
检查类型可转换性,在这种情况下,可能更灵活:p如果更具体,这篇文章的标题会更好。我自己不确定如何准确地改进,这些工具不是我的拿手好戏。