有没有办法在D中实现删除?我找不到任何引用。在以下示例中,我想使用删除器将internal
的值重置为其原始状态。如果没有 deleter 这样的东西,那么实现上述要求的首选和惯用方法是什么? (如果是这种情况,我也对设计选择感兴趣,为什么这种类型的属性函数不属于语言?)
class Class
{
private uint internal = 0;
@property uint value()
{
return this.internal;
}
@property uint value(uint input)
{
return this.internal = input;
}
}
更新
基于下面的对话:我给出了一个虚拟的例子,这让我们想到,我正在寻找的这种机制可以通过一个简单的 setter 轻松实现。属性的.init
值。然而事实并非如此。如果这个属性基本上只是几个函数调用的方便包装器怎么办?就像一些重置语义相关状态的C函数调用一样 - 这正是我的情况。
为了进一步澄清,我们讨论的是Python所具有的类似机制,它支持 getter , setter 和 deleter 。< / p>
答案 0 :(得分:2)
由于我之前从未听说过删除,我最初回答的问题与提出的问题有些不同。 D没有像Python的删除器那样的东西,下面的建议不能被称为惯用语,但它的功能基本相同,看起来有些相似。
请注意,这会导致可空类型的非直观行为 - a.value = null;
将调用特殊删除函数,而a.value = cast(Foo*)null;
将调用常规setter。所以你可能根本就不应该这样做。
更为惯用的方法是,要么设置单独的clearValue()
功能,要么在将值设置为“已删除”时进行自动清理。值(无效,0或其他)。
class Class
{
private uint internal = 0;
@property uint value()
{
return this.internal;
}
@property uint value(uint input)
{
return this.internal = input;
}
// deleter
@property uint value(typeof(null) input)
{
DoSpecialCleanup();
return this.internal = internal.init;
}
}
unittest
{
auto c = new Class();
c.value = 13;
assert(c.value == 13);
c.value = null; // Calling deleter here.
assert(c.value == 0);
}
在我对问题的初步(错误)理解中,我将其视为将所有字段重置为其初始值。这可以通过以下代码完成:
import std.traits;
void reset(T)(auto ref T t) if (is(T == Unqual!T)) {
static if (is(T == class)) {
auto data = T.classinfo.initializer[0..$];
foreach (e; FieldNameTuple!T) {
alias FieldType = typeof(__traits(getMember, T, e));
enum offset = __traits(getMember, T, e).offsetof;
static if (is(FieldType == Unqual!FieldType)) {
__traits(getMember, t, e) = *cast(FieldType*)data[offset..$];
}
}
} else static if (!is(typeof(t = T.init))) {
foreach (e; FieldNameTuple!T) {
alias FieldType = typeof(__traits(getMember, T, e));
static if (is(FieldType == Unqual!FieldType)) {
__traits(getMember, t, e) = __traits(getMember, T.init, e);
}
}
} else {
t = T.init;
}
}
class Bar {
align(16):
int n = 3;
const int n2 = 19;
}
struct Baz {
align(16):
int n = 3;
const int n2 = 19;
}
unittest {
Bar b = new Bar();
b.n = 14;
reset(b);
assert(b.n == 3);
Baz b2;
b2.n = 14;
reset(b2);
assert(b2.n == 3);
}
答案 1 :(得分:2)
简而言之 - no ,D中没有 deleter (一个Python).Python中的删除主要是因为Python的动态性。
Python3示例:
class MyType():
"""Demonstrates the use of the *deleter* ...
"""
def __init__(self):
self._someval = None
@property
def someval(self):
return self._someval
@someval.setter
def someval(self, value):
self._someval = value
@someval.deleter
def someval(self):
print('someval about to be deleted')
del self._someval
if __name__ == '__main__':
obj = MyType()
obj.someval = 42
print(obj.someval)
del obj.someval # we trigger the deleter here
print(obj.someval) # AttributeError thrown...
在上面这个简单的例子中,显然会员&#34;变量&#34; &#39; someval&#39;是动态创建的(在Python中,这些只是字典中的键......)因此可以使用 del Python关键字轻松取消/销毁。
在D中,由于显而易见的原因,这是不可能的 - 在D中,您无法动态取消设置属性! - 只要对象存在,所有成员都存在。 D的属性机制(非常简单但有效)不提供删除器 - 只有getter和setter可用,这一切都有意义......