参数,始终复制参数,除非加了​​ref​​(c++的&).

即使是引用类型(切片,关联数组,类)也是复制的,当然,复制的是钥匙.实体未复制.因此,通过它是可以直接修改原实体的.因为钥匙的能力是很强的.

当然通过值传递,因为复制的都是钥匙.

但切片,不仅仅是钥匙,一但增加超过容量.钥匙变实体,这个时候,原来的实体就不会变.

所以,对于切片,要加​​引用​​才能只用原来的​​引用​​.

同样:关联数组,初化时是个​​无效​​针.同样,将关联数组按​​ref​​传递好,不然,​​什么时候​​钥匙变实体,你也搞不清楚.

​d语言​​切片比较​​复杂​​.

​无效​​意味着未初化(一个空指针).当添加第一个时,才建立​​实体​​.因而:

import std.stdio;

void appendElement(int[string] aa) {//这里的变化不能反馈至原来的aa,参数是复制的
aa["red"] = 100;//这里钥匙变实体
//新钥匙变成新实体,与原钥匙无关
writefln("内部加元素(): %s", aa);
}

void main() {
int[string] aa;//这里还是空针.
appendElement(aa);
//如果加上 aa["blue"] = 10;
//则这个时候空针就变实体了.
//参数中复制的新钥匙就指向实体了.
writefln("(): %s", aa);//原钥匙
}

即除了​​钥匙变实体​​外,还有​​空针变实体​​,就是为了点​​懒​​初化.说实话,​​懒初化​​有的时候,没多大意义,节约不了啥.

因而,​​关联数组,类,切片​​最好都按​​引用​​传递参数.

值类型都是复制的.虽然可能复制的都是钥匙.或者可能复制的是​​空针​​.

引用类型有的复制的是​​钥匙​​,所以,你看见的仍然在原有实体上操作.

有的复制的是​​空针​​,这时,还没有建立起实体,你在函数中的操作,对外部没啥用.因为外部没有实体,你影响不了.

你影响的也是你​​参数​​新搞的实体.

​in​​=​​常 域​​,不能修改,无外部引用.

​out​​,按​​引用​​返回值.​​元组/数组​​可以替代他们.

​常​​保证​​在函数中​​不变.​​不变​​一直不变.​​可变变量​​也可通过​​常​​传递.只是​​可变​​在该​​函数​​中​​不变​​.

​ref​​按引用传值.

有些函数式编程,不允许​​按引用​​修改外部.​​只​​从返回值中变化.易于(实现,理解,维护).

​auto ref​​,模块与引用结合.这个​​按引用​​取左值,​​按复制​​取右值.

​inout​​是​​const,immutable,mutable​​的通配符.

import std.stdio;

int[] inner(int[] slice) {//这里可以扩展
if (slice.length) {
--slice.length;//尾改
if (slice.length) {
slice = slice[1 .. $];//头改
}
}

return slice;
}

void main() {
int[] numbers = [ 5, 6, 7, 8, 9 ];
writeln(inner(numbers));
}

将​​之​​扩展为​​常/不变/变​​,最后统称为​​进出​​,即怎么进来的就怎么出去.

​lazy​​,参数中的​​懒​​,为了省略计算可能的​​未用参数​​.

即,这个时候参数还没用,但已经返回了.没必要计算了.

​域​​,不在函数区间外使用.结合​​dip1000​​才能用.​​dip:d的改进措施​​,目前还在​​实验​​.

int[] globalSlice;

@safe int[] foo(scope int[] parameter) {
globalSlice = parameter;//编译错误
return parameter;//编译错误
}

void main() {
int[] slice = [ 10, 20 ];
int[] result = foo(slice);
}

域表示​​作用域​​仅限于当前函数.出了作用域,没有对其的引用.

int[] globalSlice;

@safe int[] foo(scope int[] parameter) {
globalSlice = parameter; //编译错误
//全局变量
return parameter; //编译错误
//返回切片.可能被用.
}

void main() {
int[] slice = [ 10, 20 ];
int[] result = foo(slice);
}

​共享​​要求参数可在多个线程中共享.

void foo(shared int[] i) {
// ...
}

void main() {
int[] numbers = [ 10, 20 ];
foo(numbers); //非共享变量
//->改成
shared int[] numbers = [ 10, 20 ];
foo(numbers); //编译
}

​参数中的return​​,代表​​本参数​​的生命期比​​返回​​的生命期大.即不会失效.​​return ref​​连着用.

​return ref​​==​​return scope​​.这种引用也叫​​密封引用​​.

​const​​与​​不变​​都是可传递的.

​scope​​保证不会泄露参数的引用.