[英]Provide @property for const and non-const structures in D
我用這種方式定義一個簡單的結構:
struct Person{
private string _name;
@property ref string name() { return _name; }
}
@property
注釋非常酷,但我不知道應該如何正確使用它。
以上是相當不錯的,但是我無法將Person
傳遞給需要in Person
的函數,例如:
void fun(in Person p) { ... }
為了避免復制Person
我必須使用ref
聲明參數,盡管我不修改它。
那么如何將屬性語法與const-correctness結合起來呢?
編輯:要跟進,可以同樣適用於循環嗎?
void fun(in Person[] people) {
foreach(Person p; people) { ... }
}
現在我不想復制人,但我不能使用ref Person
因為它是const。 所以我必須在循環中編寫ref const(Person) p
,它變成了loong。
通常,你會做什么
@property string name() const { return _name; }
@property void name(string value) { _name = value; }
你不會打擾ref
(當然,對於一個string
,沒有太多意義)。 對於要避免復制的更復雜類型,可以通過const ref
返回,例如
@property ref const(Foo) foo() const { return _foo; }
@property void foo(Foo value) { _foo = value; }
你可以重載二傳手,使其接受ref Foo
除了Foo
,但沒有多大意義,因為你會復制傳遞Foo
將它指定_foo
反正。
如果你真的想要,你可以通過ref
從getter返回並重載它,例如
@property ref const(Foo) foo() const { return _foo; }
@property ref Foo foo() { _foo; }
在這種情況下,非const重載可以用作setter,但是如果你要這樣做,為什么還要使用屬性呢? 此時,您可能只需將成員變量設為public,因為該屬性根本不保護它。 通過返回非const ref
,您已經失去了對成員變量設置方式的控制,並且已經有效地將其作為公共成員變量公開,除了您有額外的函數管道。 它給你的唯一好處是你可以在返回之前做一些事情,並且在調用屬性時將調用類型的不變量(如果有的話)(而不會使用公共成員變量),但因為變量可以在沒有你控制的情況下設置,與簡單地將成員變量公開的簡單性相比,這些好處具有可疑的價值。
所以,一般來說,第一個例子是要走的路,偶爾,第二個例子是更好的,但是與第三個例子相比,它可能毫無意義。
編輯:
正如Kozzi11指出的那樣 ,你可以實現第三個例子
@property auto ref foo() inout { return _foo; }
要么
@property ref inout(Foo) foo() inout { return _foo; }
而不是有兩個函數,但我對它的觀點並不比公共成員變量更好。
編輯2:關於你對問題的編輯...
如果你想避免在循環中復制,你必須明確表示類型。
foreach(p; people) { ... }
會工作,但它會復制每個Person
因為它迭代people
foreach(ref Person p; people) { ...}
要么
foreach(ref const(Person) p; people) { ...}
將避免復制每個Person
。
那這個呢:
import std.stdio;
void someFun(in Person person) {
writeln(person.name);
}
struct Person {
private string _name;
@property auto ref name() inout { return _name; }
}
void main(string[] args)
{
auto person = Person("Osoba Nova");
someFun(person);
stdin.readln;
}
編輯:for循環你可以省略類型
void fun(in Person[] people) {
foreach (p; people) {
writeln(p.name);
}
}
屬性函數只是一個函數,所以你可以重載它。
@property ref const(string) name() const { return name_; }
@property ref string name() { return name_; }
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.