天天看點

d的dip1000按域對待引用副本2

​​前文在此​​​,請先閱讀.

這裡:

ref int* index() return scope {
    return *ptr;
}      

編譯器這樣看:

ref return scope T index();      

按​

​ref​

​​和​

​return scope​

​​附加到​

​this​

​​.​

​a​

​​是​

​this​

​​.由于​

​a​

​​是​

​scope​

​​,是以​

​a.index()​

​​的傳回值也是​

​scope​

​​(​

​.1​

​​).

然後傳遞該​​

​scope​

​​傳回值給​

​int*​

​​參數不是​

​scope​

​​的​

​assign(int*)​

​​.

指派​​

​scope​

​​給​

​非域​

​​是錯誤,編譯器會​

​正确診斷​

​.

​.1​

​​就是編譯器做錯的地方.​

​中域​

​​應用至​

​ref 中​

​​,而不是傳回的​

​int*​

​​值.可通過​

​如下示例​

​展示:

ref int f(ref return scope int* x) @safe
{ 
    return *x;
}      

​注意​

​​傳回值是如何​

​沒有指針​

​​的,但是如果​

​中域​

​​時未注解它,編譯器會​

​觸發​

​​錯誤.如果搞成模闆,​

​dmd​

​​也會按"中域"​

​推導​

​​它.

​​

​中域​

​​的作用是防止按​

​引用​

​​傳回​

​f(stackPointer)​

​​,或逃逸​

​&f(stackPointer)​

​,但如下有效:

int g() @safe
{
    int x;
    int y = f(&x); // `y`不是 `域`,該是什麼?
    return y; //逃逸f的結果.
}      

原示例​

​唯一不同​

​​的是,​

​指針有效載荷​

​​為不同類型​

​(int*​

​​而不是​

​int​

​​),這不應影響示例,因為它是間接的第二層,它不應受到​

​域或中域​

​​的影響.

順便,我化簡原示例為​​

​int**​

​,因為你一般要求這樣,但看原代碼:

void scoot(scope Array!string a) @safe
{
    a[0] = a[1];
}      

這顯然不違反​

​scope​

​​并且同​

​string[]​

​​工作,是以也應同​

​庫數組類型​

​​工作,否則它是​

​dip1000​

​​的​

​糟糕設計​

​.

ref X foo(ref return scope P p)
    ReturnRef-Scope      

與你寫的​

​一緻​

​.

(備忘單已經過時了.我的錯.還記得我們将​

​returnscope​

​​更改為始終表示​

​Return Scope​

​​,而​

​ref scope return​

​​從不表明​

​Ref-ReturnScope​

​​嗎?)

為了清楚起見,把x更改為​​

​p​

​:

ref int f(ref return scope int* p) @safe
{ 
    return *p;
}      

這按​

​ref return scope​

​​編譯.這保護了p的值.而不是p的位址.因為​

​p值​

​​是傳回的值,成功編譯.

現在分開​​

​return scope​

​:

ref int f(ref5 scope return int* p) @safe
  { 
    return *p;
  }      

按​

​return ref scope​

​​編譯.錯誤:可能未傳回​

​"p"​

​​域變量.兩者都正确,​

​中域​

​​,始終按​

​中域​

​解釋.

繼續閱讀