14用d编程函数参数

参数,始终复制参数,除非加了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,模块与引用结合.这个按引用取左值,按复制取右值.
inoutconst,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保证不会泄露参数的引用.

posted @   zjh6  阅读(20)  评论(0编辑  收藏  举报  
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示