这是一种简单语言的解释程序的一部分。该语言还包括字符串,列表,函数等,以及评估程序中的相应函数evalString,evalList等函数。仅显示Number子类和evalNumber函数。
Evaluator.evaluate
函数调用Expr.eval
,每个Expr
子类都调用正确的Evaluator
函数(evalNumber
,evalString
,{{1 }}等)来计算表达式。
evalList
当我尝试构建它时,我得到
import std.stdio;
import std.string;
abstract class Expr {
Out eval(Out)(Evaluator!Out evaluator);
}
class Number: Expr {
double num;
this(double _num) { num = _num; }
override Out eval(Out)(Evaluator!Out evaluator) {
return evaluator.evalNumber(this);
}
}
class Evaluator(Out) {
Out evaluate(Expr expr) {
return expr.eval(this); // ### Error is here ###
}
abstract Out evalNumber(Number number);
}
class ExprPrinter: Evaluator!string {
override string evalNumber(Number num) {
return format("%s", num.num);
}
}
void main() {
Number n = new Number(5);
auto printer = new ExprPrinter();
writefln("Number: %s", printer.evaluate(n));
}
如果我正确阅读了mangle,则编译器会说第19行上的example.o: In function `_D7example__T9EvaluatorTAyaZQp8evaluateMFCQBo4ExprZQBb':
/home/neniu/projects/duover/source/example.d:19: undefined reference to `_D7example4Expr__T4evalTAyaZQkMFCQBf__T9EvaluatorTQBaZQpZQBh'
collect2: error: ld returned 1 exit status
Error: linker exited with status 1
(在代码中标记)是指未定义的函数,而是(在这种情况下){{1 }}函数应该就是那个函数。
我尝试更改第19行以包括Out专业化
expr.eval
但这根本没有区别。
我在这里想念什么?如何获得Number.eval
的电话才能解析为return expr.eval!Out(this);
?
这与DMD 2.081.1。一起使用。
谢谢。
*&当我尝试构建它时,我得到
expr.eval(this)
如果我正确阅读了mangle,则编译器会说第19行的expr.eval(在代码中标记)是指未定义的函数,但是(在这种情况下)Number.eval函数是应该是那个功能。
我尝试更改第19行以包括Out专业化
返回expr.eval!Out(this);
但这根本没有区别。
我在这里想念什么?如何获取expr.expr(this)调用以解析为Number.eval?
这与DMD 2.081.1。一起使用。
谢谢。
*编辑*
我尝试使Number.eval
抽象(对类本身使用example.o: In function `_D7example__T9EvaluatorTAyaZQp8evaluateMFCQBo4ExprZQBb':
/home/neniu/projects/duover/source/example.d:19: undefined reference to `_D7example4Expr__T4evalTAyaZQkMFCQBf__T9EvaluatorTQBaZQpZQBh'
collect2: error: ld returned 1 exit status
Error: linker exited with status 1
限定符,因为这是每个子类都必须重写的功能:
Expr.eval
但是现在编译器抱怨
abstract
我不希望abstract class Expr {
abstract Out eval(Out)(Evaluator!Out evaluator);
}
是最终的。我没有做任何使example.d(5): Error: function `example.Expr.eval!string.eval` final functions cannot be abstract
example.d(28): Error: template instance `example.Expr.eval!string` error instantiating
example.d(35): instantiated from here: Evaluator!string
最终的事情。我不明白为什么这会使Expr.eval
成为最终定论。如何使Expr.eval
不是最终的,以便可以使它抽象,所以我可以-不,必须-覆盖它?
是否将声明为Expr.eval
(“您必须重写此功能”)与声明为Expr.eval
(“您不能重写此功能”)恰好相反?
答案 0 :(得分:1)
不是将某些东西声明为抽象的(“您必须重写此函数”)与将其声明为最终的(“您无法重写此函数”)完全相反吗?
是的。但是模板化函数始终是最终的。 IMO,HSSFColor.getIndexHash().get(myCell.getCellStyle().getFillBackgroundColor())
上应该有一条错误消息,但是显然编译器选择保持沉默。您需要将override Out eval(Out)(Evaluator!Out evaluator) {
设为模板,或者将其移为非成员函数。
您要做的实际上是多次调度,该调度在OpenMethods中作为库实现。仅知道您所显示的代码,很难分辨这是否正是您所需要的。
答案 1 :(得分:0)
Expr.eval
需要了解Out
参数类型的唯一原因是因为我无法找到一种方法来获取Evaluator.evaluate
来识别其运行时类型输入。如果我可以做类似的事情
// In class Evaualor. Maybe (Out) is a parameter the class, not the method.
Out evaluate(Out)(Expr e) {
if (isType!Num(e)) {
return evalNum(cast(Num) e);
}
else if (isType!Str(e)) {
return evalStr(cast(Str) e);
}
else if (isType!List(e)) {
return evalList(cast(List) e);
}
and so on
}
然后,Expr
不需要了解Evaluator
或它的evaluate
方法发出的类型。
是否存在确定此类变量的实际运行时类型的方法?那会节省我一些时间。