为D中的const和非const结构提供@property [英] Provide @property for const and non-const structures in D
问题描述
我以此方式定义了一个简单的结构:
I define a simple struct this way:
struct Person{
private string _name;
@property ref string name() { return _name; }
}
@属性
注释确实很酷,但是我不知道如何正确使用它。
The @property
annotation is really cool, but I don't know how should I use it properly.
上面的代码还可以,但是我不能通过人员
到需要<人中的$code>的功能,例如:
The above is quite ok, but I cannot pass a Person
to a function requiring in Person
for instance:
void fun(in Person p) { ... }
为避免复制人
我必须用 ref
声明参数,尽管我没有对其进行修改。
To avoid copying Person
I have to declare the parameter with ref
, though I don't modify it.
那么如何将属性语法与const-正确性结合起来?
So how to combine the property syntax with const-correctness?
编辑:
要进行跟进,是否可以将同样的方法应用于循环?
edit: To follow up, can the same apply to looping?
void fun(in Person[] people) {
foreach(Person p; people) { ... }
}
现在我不知道'不想复制人员,但是我不能使用 ref Person
,因为它是const。因此,我必须在变成loong的循环中编写 ref const(Person)p
。
now I don't want to copy person, but I can't use ref Person
since it's const. So I have to write ref const(Person) p
in the loop which becomes loong.
推荐答案
通常,您会做的是
@property string name() const { return _name; }
@property void name(string value) { _name = value; }
,您就不必担心 ref
(当然,对于字符串
来说,意义不大)。对于要避免复制的更复杂的类型,可以通过 const ref
返回,例如
and you wouldn't bother with ref
(certainly, for a string
, there isn't much point). For more complex types that you want to avoid copying, you can return by const ref
, e.g.
@property ref const(Foo) foo() const { return _foo; }
@property void foo(Foo value) { _foo = value; }
您可以超载设置程序,使其接受 ref Foo
和 Foo
一样,但是没有什么意义,因为您将复制传入的 Foo
始终将其分配给 _foo
。
You could overload the setter so that it accepted ref Foo
in addition to Foo
, but there isn't much point, since you'd be copying the passed in Foo
to assign it to _foo
anyway.
如果您真的想要,您可以从吸气剂中通过 ref
返回并重载它,例如
And if you really want to, you can return by ref
from the getter and overload it, e.g.
@property ref const(Foo) foo() const { return _foo; }
@property ref Foo foo() { _foo; }
在这种情况下,可以将非const重载用作setter,但如果要这样做,为什么要打扰财产?那时,您最好将成员变量设为公开,因为该属性根本无法保护它。通过返回非const ref
,您将失去对成员变量设置方式的控制,并已将其有效地公开为公共成员变量,除了拥有更多的它周围的功能。它给您带来的唯一好处是您可以在返回之前做一些事情,并且在调用属性时将调用类型的不变式(如果有的话)(而不会使用public成员变量),但是因为变量可以如果在没有控制的情况下进行设置,那么与简单地简单地将成员变量设为公共状态相比,这些好处的价值值得怀疑。
in which case the non-const overload can be used as a setter, but if you're going to do that, why bother with a property? At that point, you might as well just make the member variable public, because the property isn't protecting it at all. By returning non-const ref
, you've lost control over how the member variable is set and have effectively exposed it as a public member variable except that you have the extra plumbing of the function around it. The only advantages that it gives you are that you can do something before returning and that the type's invariant (if any) will be called when the property is called (whereas it won't with a public member variable), but because the variable can be set without you're control at that point, those benefits are of questionable value in comparison to the simplicity of simply making the member variable public.
因此,通常,第一个示例是行之有效的方法,偶尔,第二个示例更好,但是与第三个示例一起使用则毫无意义。
So, in general, the first example is the way to go, and once in a while, the second is better, but it's arguably pointless to go with the third example.
编辑:
Kozzi11指出可以将第三个示例实现为
As Kozzi11 points out, you can implement the 3rd example as
@property auto ref foo() inout { return _foo; }
或
@property ref inout(Foo) foo() inout { return _foo; }
虽然没有两个功能,但我的观点并没有比公共成员更好变量仍然适用。
instead of having two functions, but my point about it not really being much better than a public member variable still applies.
编辑2:对于您对问题的编辑...
EDIT 2: With regards to your edit to the question...
如果要避免在循环中进行复制,则必须明确指定类型。
If you want to avoid copying in the loop, you're going to have to be explicit with the type.
foreach(p; people) { ... }
可以,但是会复制每个个人人
遍历个人
,而
will work, but it will copy each individual Person
as it iterates over people
, whereas
foreach(ref Person p; people) { ...}
或
foreach(ref const(Person) p; people) { ...}
将避免复制每个 Person
。
这篇关于为D中的const和非const结构提供@property的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!