dlang语法的简单整理

dlang整理

为什么使用dlang

优点:
    快速,开发高效的,方便,无虚拟机的,快速的,高性能的,垃圾回收
缺点:
    语法较为复杂,支持gc

曾经很喜欢dlang,资料少,竟然没有招聘用dlang的,so,只能偶尔玩玩。

基础类型和变量定义

基础类型
    char,byte,short,int,long,float,double bool,string, wstring,dstring
定义类型
    int a=1;
    auto a = 2;
类型 typeid,typeof   typeid(typeof(a))
定义固定数组 int[3] arr=[1,2,3];
定义动态数组  auto arr2[] = [1,2,3];
定义关联数组 int[string] arr3 = ["pi":1,"perl":2];
定义函数auto func = function double(int x){return x/10.0;}
如果函数想运用外部变量使用delegate代替function 
        float x = 10.0;
        auto func2 = delegate double(int y){return y/x};
 显示类型
    typeid(typeof(a))  或者 typeof.stringof
 类型强制转换 
    cast(float)a
 使用is判断类型
    是否存在类型 is(int[])  is(add) is(f2)
    类型是否相同 is(int == uint)
    类型是否能格欧转换  is(int : long)
    专用的检测类型 is(typeof(f2) == function)

语句

 变量声明语句什么的就不再赘述了
 if else while do while for  与c一直不再特别的说明
 dlang可以随意定义内部的临时变量
    {
        int ib = 12;
    }
 static if  静态条件编译,有点像#ifdef #else #endif
    static if(#静态条件){
        //do1
    }else{
        //do2
    }
 final switch 强制条件覆盖,条件必须是静态数据
     final switch(s1){
        case  c1:
            do;
            break;
        case c2:
            do;
            break;  
     }
with 定义结构变量
        point p;
        with(p){
            x = 1;
            y = 2;
        }
退出时的执行scope(success),scope(faild)
代码退出时按照栈执行的,先进后出
        scope(success){
            do1
        }
        scope(success){
            do2
        }

数组

在D语言中的数组是胖指针。 头指针+长度 或者头指针+尾指针
在D语言中动态数组和静态数组会有一点不同。
定义动态数组
    int[] arr = new int[10];
    int[3] arr2 =[1,2,3];
动态数组长度
    writeln(arr.length);
动态数组的拷贝
    动态数组的复制会引用同一份副本
        auto arr3 = arr;
        arr3[0] = 1;
        assert(arr[0] ==1);
    如果真的需要复制可以采用
        auto arr4 = arr.dup;
        arr4[0] = 3;
        assert(arr[0] != 3);
 数组拼接
        arr = arr ~ 11;
 数组分割
    arr[1..2];
 数组支持的基本运算
    + - * 、 % ^ & ~ = += -= *= /= %= ^= &= |=
    arr5[] = arr2[] + arr1[]
 数组的扩张和收缩
    arr ~= 13;
    arr.length = 100;
    arr[1..$-1];
 数组的遍历
    foreach(v;arr) writeln(v);
    foreach(ref v;arr) v++;
 静态数组的声明
    int[3] arr10 = [1,2,3];
 静态数组可以支持边界检查
 静态数组的切割会产生动态数组
 静态数组的复制可以产生新的数组
    auto arr11 = arr10;
    arr11[0] =123;
    assert(arr10[0] != 123);
 多维数组不再多说,和其他语言类似
 关联数组
    定义
        int[string] arr2 = ["a":1,"b":2];
    长度
        assert(arr2.length == 2)
    赋值
        arr2["a"] = 11;
    获取值
        arr2.get("a",1234); //如果取不到则为1234
    删除值
        arr2.remove("a");
    遍历
        foreach(k,v;arr){
            write(k,"=>",v,"\t");
        }

函数

基本的函数
    bool max(int a,int b){
        return a > b;   
    }
动态数组传递给函数
    void func(int x){x++;}
    void gunc(int[] x){x=[2,3,4];}
    void sunc(int[] x){x[0] = 21;}
    auto x = [111,222];
    gunc(x);
    assert(x == [111,222]);
    sunc(x);
    assert(x==[21,222]);
ref修改变量的值
    void change(ref int x){x++;};
    int x = 11;
    change(x);
    assert(x == 12);
函数返回refer
    ref int getX(int x){return x;}
    int x11 = 12;
    int y =0;
    y = getX(x11);
    y++;
    assert(x11 == 12);
in和out修饰符
    in 让参数只可以读,out允许外部向内部传入值
    此时y相当于前面加了ref
    int func_inout(in int x,out int y){
        y = x+1;
        return x;
    }
静态变量
    static int fc = 1;
    void func_static(int x){fc++;}
查找函数
    bool find1(int[] arr,int val){
        foreach(v;arr){
            if(v == val) return true;
        }
        return false;
    }
    int[] find2(int[] arr,int val){
        while(arr.length > 0 && arr[0] != val){
            arr = arr[1..$];
        }
        return arr;
    }
查找函数中添加泛型
    T[] find3(T)(T[] arr,T val){
        while(arr.length > 0 && arr[0] != val){
            arr = arr[1..$];
        }
        return arr;
    }
   int[] list = [1,2,3,4,5];
   assert(find3!(int)(list,3) == [3,4,5]);
对于多个类型的情况,可以在函数前面增加参数约束。
    T[] find4(T,E)(T[] arr,E val)
    //T和E能相互转化
    if(is(typeof(arr[0] != val) == bool))
    {
        while(arr.length > 0 && arr[0] != val){
            arr = arr[1..$];
        }
        return arr;
    }
    assert(find3(list,3) == [3,4,5]);
让t变得更加通用,在一个数组中寻找另外一个数组
    T[] find5(T,E)(T[] arr,E[] arr2)
    if(is(typeof(arr[0..1] == arr2) : bool))
    {
        while(arr.length > arr2.length){
            if(arr[0..arr2.length] == arr2) break;
            arr = arr[1..$];
        }
        return arr;
    }
函数的优先调用
        bool myprint(int x){
            return is(typeof(x) == int);
        }

        bool myprint(double x){
            return is(typeof(x) == double);
        }
        myprint(1);//优先调用myprint(int x)
函数别名调用
    T[] finderSenior(alias func,T)(T[] input)
    if(is(typeof(func(T[0])) == bool))
    {
        for(;input.length > 0;input = input[1..$]){
            if(func(input[0])) break;
        }
        return input;
    }
    auto senior_list = [22,3,12,-7,-9,32];
    assert(findSenior!(function bool(int x){return x > 30;})(senior_list) == [32]);
    int z = 30;
    //senior function delegate调用委托函数。委托函数可以访问外部变量
    assert(findSenior!(delegate bool(int x){return x > z;})(senior_list) == [32]);
    auto myfunc = function bool(int x){ return x < 0;};
    auto senior_list2 = findSenior!(myfunc)(senior_list);
    //auto list2 = findSenior!(myfunc,int)(list);
    assert( senior_list2 == [-7, -9, 32]);
函数内部的函数
    int[] outfunc(int[] input,int z){
        bool infunc(int x){
            return x >= z;
        }
        static int zz = 30;
        static bool infunc2(int x){
            return x > zz;
        }
        return finderSenior!(infunc)(input);
    }
闭包
    T[] delegate(T[])find9(T)(T x)
    if(is(typeof(x == x) == bool))
    {
        return delegate(T[] a){return findList(a,x)};
    }
    auto delegate_func = finder(5);
    auto delegate_func_new = finder("ho");
    //senior function test
    auto senior_list = [22,3,12,-7,-9,32];
    int z = 30;

    assert(delegate_func([1,2,3,4,5,6]) == [5,6]);
    assert(delegate_func_new(["hi","ho","wo"]) == ["ho","wo"]);
可变参数的函数,参数结构相同
    double avg(double[] values...){
        return reduce!((a,b){return a+b;})(0.0,values)/values.length;
    }

可变参数的函数,参数结构不相同
    void writeln_m(T...)(T args){
        foreach(arg;args){
            stdout.rawWrite(to!string(arg));
        }
        stdout.rawWrite("\n");
        stdout.flush();
        foreach(k,v;args){
            writeln(k,":",typeid(T[k]),"~~",v);
        }
    }
    writeln_m(1,2,1.1,"hell",[1,23]);
元组--打包函数参数
    Tuple!(int,double) tv = tuple(1,1.2);
    void fun(T...)(T args){
        gun(tuple(args));
    }
    void gun(T)(T value){
        writeln(value.expand);
    }
纯函数
    pure int mypure(int x){
        return x+10;
    }
不抛出异常的函数
    nothrow void tryThrow(){
        try{
        }catch(Exception e){
        }
    }

类支持各种类型的变量
非静态的,静态的,静态的变量初始化一次后不可改变
支持普通方法
构造器语法this() ~this()
也支持静态构造器static this() static ~this();
静态构造方法在构造方法前面运行
final可以定义不可覆盖的类       
类也支持property方法           
this() 的执行顺序是: 分配内存,初始化,冠名,构造函数的调用
~this()的步骤 对象冠名后是活的。所有引用消失,检查是否可以回收,某个时间点回收,释放已解除分配的对象

继承与接口

子类B会自动调用父类A的构造方法
子类要覆盖父类的方法必须添加override关键字
final可以修饰类,方法,和变量,被修饰的类,方法,变量禁止覆盖
也支持子类向上转型为父类,但是不支持父类转型为子类
也支持抽象类,使用abstract关键字
d语言中所有的类都有共同的父类object
object自带如下方法
    toString 
    toHash 
    opEquals(Object ths)
    opCmp(Object ths) 
    static Object factory(string classname)
d语言的接口可以增加修饰符 private protected public 
d语言也支持抽象类,使用abstract语法。
d语言也支持,内中嵌套类,方法中嵌套类,

结构体

结构体和类的不同我也很困惑,我的理解,class表示逻辑操作,struct表示数据对象
列举下类和struct的不同
    结构体能代替对象,反过来不行
    结构体不支持继承和接口的实现
    在结构体内不支持super
    结构体不允许改写,所有方法都是最终的
    结构体不能喝synchronized和struct一起使用
    struct不支持默认的构造方法this()
    struct不支持定义构造方法this(this)
    结构体不支持protected修饰符
结构体的复制,是值传递,对象是引用
    比如 xx s1;auto s2 = s1;s1和s2指向两个不同的对象
结构对象传递给函数是值传递
结构对象的生命周期非常有限,类似函数里面临时变量的周期
构造函数,
    默认不运行代码实现this()构造器
    但是声明的时候可以使用默认的
转发构造函数是被允许的
this(this)如果结构里面含有引用类型数据
    可以使用this(this)在拷贝的时候做些特别的操作
可以定义一个析构函数~this()
可以定义任意数量的的静态构造器和析构函数
结构可以定义方法和静态方法
@property支持属性的方式调用方法
结构内部可以嵌套类和结构
类内部也可以嵌套结构和类
#disable可以禁用一些方法
结构体的偏移align消除结构见的间隙
联合union和c语言一样
枚举值和枚举类型
    enum ae =123;
    enum a1{aa,ab,ac};

tuples,alias和mixin 模板注入代码 泛型

tuple不可改变的元组
    导入import std.typecons; 包
    定义 auto tuple1 = tuple(1,"tutples");
    或者 auto tuple1 = Tuple!(int,"id",string,"value")(12,"tom");
访问元组
    tuple1[0],tuple1[1]
元组可以扩展
    myTuple.expand
元组也可以剪切
    myTuple[$-2..$]
alias有三种格式
    alias new_name = existing_name;
    alias existing_name new_name;
    alias expression alias_name ;
    别名方法,别名tuple,别名常用类型,别名类,别名this
泛型基础语法 xx(T,E,XX..) class xxx(T)
泛型分三种情况
    方法泛型 funcname(T)()  调用 funcname!(int)()
    方法多参数泛型funcname(T,E)()
    类的泛型  class xxx(T)  classname A!T a= new  classname A!T()
mixin 基础语法 mixin (compile_time_generated_string) 
mixin归纳成三种情况
    字符串注入 mixin(xxx)
    模板注入 mixin xxx!(x,x)
    命名空间注入 mixin xxx a

修饰符,错误处理,契约编程 模块重载

immutable 
    可以用来修饰方法参数也可以修饰构造函数
    immutable int[] 和imutable(int)[]是不同的前者是整个数组后者只针对部分变量
    一个例子看出不同
        immutable(int[]) a = [1,2,3];
        //a[0] = 11;//错误
        //a = [3,2,1];//错误
        immutable(int)[] b = [1,2,3];
        //b[0] = 11;//错误
        b = [3,2,1];//正确
    构造函数的例子
        this() immutable{
            count = 1;
            desc = "done";
        }
        immutable(BookOperator) bo = new immutable(BookOperator);
const 用来修饰常量
错误处理
    异常继承Exception 
    函数可以声明为nothrow
    捕获异常还是try-catch-finnaly体系
契约编程
    判断输入,判断输出,判断返回结果 in{} out{} body{}
模块的问题
    定义模块module company.employee;
        company文件下的employee类或者struct
    模块的导入默认只会导入我们需要的
        例如import std.stdio  只会导入stdio下的方法或者是类
        -Ipath         where to look for imports
        跨模块重载-排序的,避免的冲突
    别名
        import widget:fun,gun;
        import list = util.container.finite.linear.list;
        alias util.container.finite.linear.list list;
    导入所有的包。public import
        module animal;
        public import animal.cat;
        public import animal.dog;
        public import animal.horse;
    static import
    deprecated声明。
        deprecated("Please use doSomething() instead.")
    模块的析构函数和构造函数
        static this() and static ~this()
        能加上shared表示所有模块共享
        构造函数的顺序和析构函数的顺序是反的
        不同模块间的构造方法依次导入
    安全性 @safe @trusted @system 可以在编译的时候加上条件
    调用c语言
        todo
    debug(level)
    version(tag)

重载

Operators对象的基本操作,操作符重载
一元重载
    - + ~ * ++ --
    XX opUnary(string op)(){}
     例如
  Box opUnary(string op)()
  {
      if(op == "++")
      {
         Box box = new Box();
         box.length = this.length + 1;
         box.breadth = this.breadth + 1 ;
         box.height = this.height + 1;
         return box;
      }
  }
二元重载
    + - * / % ^^ & | ^ << >> >>> ~ in
     Box opBinary(string op)(Box b)
  {
     if(op == "+")
     {
        Box box = new Box();
        box.length = this.length + b.length;
        box.breadth = this.breadth + b.breadth;
        box.height = this.height + b.height;
        return box;
      }
  }
比较重载
    < <= > >=
    int opCmp(const ref Box box) const{}

并发编程

如何启动线程
    使用std.concurrency
    通过spawn方法spawn(&func,arguments..)
使用immutable 实现消息共享
数据传递
    发送消息tid.send(tid,argu..)
    接收消息
    receive(
        (string s){},
        (int x){},
    );  
    receiveTimeout(
    );
共享类型shared
    可以修饰变量
    修饰结果或者类
基于锁的同步synchronized
    可以修辞类和方法
避免死锁
pragma 用于编译器的提示信息。

你可能感兴趣的:(d语言)