D中有"deleter"吗?

Is there a "deleter" in D?

有没有办法在 D 中实现 删除器?我找不到任何参考资料。在下面的示例中,我想使用 deleterinternal 的值重置回其原始状态。如果没有 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 具有的类似机制,它支持 gettersetter删除器.

因为我以前从未听说过删除器,所以我最初回答的问题与被问到的问题有些不同。 D 没有任何类似 Python 的删除器,下面的建议不能称为惯用的,但它本质上做同样的事情并且看起来有些相似。

请注意,这将导致可空类型的非直观行为 - a.value = null; 将调用特殊删除函数,而 a.value = cast(Foo*)null; 将调用常规 setter。所以你可能根本不应该这样做。

一种更惯用的方法是拥有一个单独的 clearValue() 函数,或者在值设置为其 'deleted' 值(空值、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);
}

简而言之 - 没有,D中没有deleter(a la Python)。[中的删除器=30=] 的存在主要是因为 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...

在上面的这个简单示例中,很明显成员 "variable" 'someval' 是动态创建的(在 Python 中,这些都只是字典中的键...)并且作为使用 del Python 关键字可以很容易地 unset/destroyed。

在 D 中,这是不可能的,原因很明显 - 在 D 中,您不能动态取消设置属性! - 只要对象存在,所有成员就存在。 D 的 属性 机制(非常简单,但有效)不提供删除器 - 只有 getter 和 setter 可用,这一切都有意义...