2010-10-05 87 views
5

我有一个班级,我正在实施的范围。我想以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)。

我在做什么错?

回答

4

你要做什么取决于D社区调用统一函数调用语法。这是使用与成员函数相同的语法来调用非成员函数的能力。这已经在数组中实现了很长时间,并且对于采用它的程度还有一些争论。已经决定应该为所有类型实现它,但编译器实现者Walter Bright尚未开始这样做,因为他在64位支持上一直在狂热地工作。

统一函数调用语法在Andrei Alexandrescu的书“The D Programming Language”中描述,它被认为是D2的权威指南。目前缺乏实施被认为是一个错误。这应该在几个版本中修复。

+0

感谢您的评论。我的类是不可变的,所以我实际上在类中本身不能有一个popFront成员。但我确实创建了一个“PersistentListRange”子类,所以我可以做foreach(i; lst.range),并且工作得很好。 – 2010-10-06 12:58:05

3

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在所有情况下都会做的事情,除了数组之外,显然不能将它们作为其类型的一部分,并且必须使用它们的功能来调用它们,就好像它们是成员函数一样才能工作。