非会员范围功能
问题描述:
我有一个班级,我正在实施的范围。我想以phobos库的方式实现这些功能,即在主类之外。非会员范围功能
void popBack(T)(ref T[] a) if (!is(Unqual!T == char) && !is(Unqual!T == wchar))
{
assert(a.length);
a = a[0 .. $ - 1];
}
这里是我的版本:
void popFront(T)(ref PersistentList!(T) a)
{
a = a.next();
}
当我尝试编译这段代码有forech,我得到:
Error 1 Error: no property 'popFront' for type 'stmd.PersistentList!(int).PersistentList' main.d
我会会员代码移动到主类,但由于我正在修改输入“ref”值,我不能使用popFront()我真的需要popFront(ref a)。
我在做什么错?
答
你要做什么取决于D社区调用统一函数调用语法。这是使用与成员函数相同的语法来调用非成员函数的能力。这已经在数组中实现了很长时间,并且对于采用它的程度还有一些争论。已经决定应该为所有类型实现它,但编译器实现者Walter Bright尚未开始这样做,因为他在64位支持上一直在*地工作。
统一函数调用语法在Andrei Alexandrescu的书“The D Programming Language”中描述,它被认为是D2的权威指南。目前缺乏实施被认为是一个错误。这应该在几个版本中修复。
答
Phobos仅在数组的struct/class之外实现范围函数。数组允许你在它们上调用函数,就像它们是成员函数一样。所以,如果你有这样的功能:
int func(int[] arr)
{
return arr[0];
}
你可以调用它像这样
auto arr = [1, 2, 3];
auto val = arr.func();
代替
auto val = func(arr);
如果能够做到这一点与所有类型的被称为通用函数调用语法,但这在D中目前还不合法,尽管它看起来可能会被添加。
除非您希望与其他范围类型共享该实现,否则实际上没有理由在范围类型外声明您的范围函数,因为内部实现必须处理容器类型如何维护其数据。所以,你可能只是让它们成为你的范围类型的一部分。这就是Phobos在所有情况下都会做的事情,除了数组之外,显然不能将它们作为其类型的一部分,并且必须使用它们的功能来调用它们,就好像它们是成员函数一样才能工作。
感谢您的评论。我的类是不可变的,所以我实际上在类中本身不能有一个popFront成员。但我确实创建了一个“PersistentListRange”子类,所以我可以做foreach(i; lst.range),并且工作得很好。 – 2010-10-06 12:58:05