Dart 基础语法入门

2023年 10月 16日 86.9k 0

  • Dart支持泛型,例如List表示任意类型对象组成的列表

    变量

    • 1、使用var 声明变量,可以赋予不同类型的值,var可以在运行中推导出变量的类型,确定了便不能更改类型

    • 2、使用Object,这个关键字大家应该都很熟悉,Java中的所有对象的父类就是Object,Object和var不同的点是即使赋了初始值,也可以指定别的类型,例如int,String,Num等。

    • 3、dynamic 和Object非常类似,唯一的区别就是如果你调用一个本身不存在的方法,Object会在编译器就直接报错,而dynamic则会在运行的时候才会抛出异常

        //var定义变量
        var name = 3;
        name = "Bob"; // 编译报错:A value of type 'String'can't be assigned to a variable of type 'int'.
        //Object定义变量
        Object a = 'blob';
        a = 123;
        a = [];
        //  动态定义变量
        dynamic _name = 'Bob';
        _name = 3;
        // object和dynamic的区别
        Object testa = "asd";  
        // testa.substring(1);//编译失败:The method 'substring' isn't defined for the type 'Object'.  
          //正确1强转 :print("Object>>>>"+(testa as String).substring(1));  
        dynamic testdy = "restdy";  
         print(testdy.substring(1));//编译通过
         
      

    常量

    • 常量在dart中可以用final和const来修饰
    • final包含了const的功能,区别在于
      1、final可以接受运行时的数据,const则只能接受编译时的数据
      2、const 必须给一个明确的编译常量值(即编译期间就确定的值),final 可以一开始不赋值。
      3、final 是惰性初始化,运行时第一次使用前才进行初始化
      4、const在修饰类中变量时,则必须加上static变量
    //-----第一点:-----
    final time = DateTime.now();
    // const time2 = DateTime.now();//编译报错:Const variables must be initialized with a constant value.
     
     //-----第二点:-----
     
     //正确
      const atest = 1;
      const btest = atest > 1 ? 2 : 1;
    //错误
      var atest2 = 1;
      //下面这句报错:Const variables must be initialized with a constant value
      // const btest2 = atest2 > 1 ? 2 : 1;
    
    //如果字符串是const 声明的编译时常量,编译时常量 (null、数字、字符串、布尔) 才可以作为该字符串字面量的插值表达式。
    // 这些在 const 声明的字符串常量中能用
      const aConstNum = 0;
      const aConstBool = true;
      const aConstString = 'a constant string';
    // 这些在 const 字符串中不能用,用 var 声明的才有用
      var aNum = 0;
      var aBool = true;
      var aString = 'a string';
      const aConstList = [1, 2, 3];
      const validConstString = '$aConstNum $aConstBool $aConstString';
      //编译出错:In constant expressions, operands of this operator
      // must be of type 'bool', 'num', 'String' or 'null'.
      // const invalidConstString = '$aNum $aBool $aString';
      var validConstString2 = '$aNum $aBool $aString $aConstList';
      print(validConstString2);
    
    
    //--第三点-----
    
    // const a; //编译报错: The constant 'a' must be initialized.
    	final testfinal;
    	testfinal = "3";
    
    //第四点
    class Test{
       const String name="jack";//报错提示:尝试将字段声明为
       //最终字段,或添加关键字“静态”。
    
      void getString(){
        const String name2="jack";
      }
    
    }
    

    5、final 只可用来修饰变量, const 关键字不仅仅用来定义常量,还可以用来创建常量值,该常量值可以赋予给任何变量。也可以将构造函数声明为 const,这种类型的构造函数创建的对象是不可改变的。
    6、const 修饰对象时,要在构造方法加const

    //5、const修饰的数组列表不能被修改
    	var foo = const [1,2,3];
    	// foo[0] = 3;//报错:Cannot modify an unmodifiable list
    	// print("foo:{$foo}");
    	
    	//final定义的数组列表可以被修改
    	final bar =  [1,3,4];
    	bar[0] = 9;
    	print("bar:${bar}");//正确
    
    	//一样不能被修改
    	final barconst = const [];
    	// barconst[0] = 9;//报错:Cannot modify an unmodifiable list
    
    	const baz = []; // 相当于`const []`
    	baz.add("value");
    	print(baz);//报错:Cannot add to an unmodifiable list
    
    	//const 修饰对象
    	//const 修饰对象时,要在构造方法加const
    	//否则会报:Cannot invoke a non-'const' constructor where a const expression is expected.
    	
    	const p1 = const Person('myname');
    	const p2 = Person('myname'); // 右边的const 可以省略
    	var p3 = const Person("myname");
    
    	print("---------${identical(p1, p2)}");// true
    	print("---------${identical(p1, p3)}");// false
    
    • 关于identical函数(检查两个引用是否指向同一个对象。)
    //官方说明
    var o = new Object();
     var isIdentical = identical(o, new Object()); // false, different objects.
     isIdentical = identical(o, o); // true, same object
     isIdentical = identical(const Object(), const Object()); // true, const canonicalizes
     isIdentical = identical([1], [1]); // false
     isIdentical = identical(const [1], const [1]); // true
     isIdentical = identical(const [1], const [2]); // false
     isIdentical = identical(2, 1 + 1); // true, integers canonicalizes
    

    关键字

    Dart 基础语法入门-1

    • 带有上标1的是上下文关键字,仅在特定位置具有含义。它们是可以在任何地方作为标识符。
    • 带有上标2的单词是内置标识符。为了简化将JavaScript代码移植到Dart的任务,这些关键字在大多数地方都是有效的标识符,但它们不能用作类或类型名称,也不能用作导入模块时的前缀。
    • 带有上标3的单词是与Dart 1.0发布后添加的异步支持相关的关键字。

    part和part of

    这个关键字可以把文件分成多个文件,将一个大的lib拆分成多个小的文件

    注意part跟part of 要配套使用

    • A类
        part "B.dart"//指明B是A的一部分
    
    • B类
        part of "A.dart"//指明B是属于A的一部分
    

    运算符

    Dart 基础语法入门-1

      //赋值运算符
      var a = 1;
      int? b;
      print(b);//null
      b ??= 2; // 如果 b 为空的话就把 2 赋值给 b
      print(b);//2
      a += 0;
      print(a);//1
    
    //  算数运算符
    //a=1,b=2
      print(a + b);//3
      print(a - b);//-1
      print(a * b);//2
      print(a / b);//0.5   在java中会进行取整运算,在dart中会自动推导成小数
      print(a % b); // 取余  1
      print(a ~/ b); // 取整 0 ===>和java的取整一样
      //以下和java一样
      // a++ // 先运算再自增
      // a-- //先运算再自减
      // --a // 先自减再运算
      // ++a // 先自增再运算
    
      print("========关系运算符========");
      ////a=1,b=2
      //关系运算符
      print(a == b);//false
      print(a >= b);//false
      print(a  "zhujiang";
    String test1(){
      return "zhujiang";
    }
    
    //可选命名参数
    main() {
      print(add(a: 1, b: 3));
    }
    
    int add({int a = 1, int b = 0}) {
      return a + b; // 输出4
    }
    //可选位置参数
    int add2(int a,[int b = 2,int c = 3]) {
      return a + b;
    }
    print(add2(1));//3
    print(add2(1,2));//3
    print(add2(1,1,3));//2
    //必选在可选参数之前
    int add2([int b = 2,int c = 3],int a) { // 报错:Expected to find ')'.
      return a + b;
    }
    int add3(int c,{int a = 1, int b = 0}) {// 报错:Expected to find ')'.
      return a + b;
    }
    

    匿名函数

    • 分为有参匿名和无参数匿名
    //无参
    var printFun = () => print("**无参匿名函数**");
    
    //有参
    var printFun2 = (name) => print("**有参匿名函数 $name**");
    printFun2("sss");
    

    闭包

    • Dart内也有闭包的定义,这和JavaScript相似
    Function makeAddFunc(int x) {
      return (int y) => x + y;
    }
    var makeAddFun = makeAddFunc(11);
    
    void main(){
      print(makeAddFun(10));//输出21
    }
    

    词法作用域

    • Dart 的作用域是词法作用域,跟 JavaScript 一样,在写代码的时候就确定了。
    void test1(){
      var a = 2;
      void test2(){
        var b = 3;
        print(a);
      }
    }
    

    逻辑控制

      // for 循环
     for (var i = 0; i  0) {
        print(while1);
        while1--;
      }
      print("======do-while======");
      // do-while
      var i = 5;
      do {
        print(i);
        i--;
      } while (i > 0);
    
    //  do while 跟 while 的区别是即使不满足条件,do while 循环也会 do 一次;while 循环不会
    
    //  断言——assert
    //   assert(1  2, '1>2 is wrong');//当表达式为false,抛出异常:  '1 > 2': 1>2 is wrong
    
      print("====异常-捕获=====");
    
    //  异常-捕获
    
      try {
        // throw Error(); // 输出:No specified type, handles all error Instance of 'Error'
        //抛出异常
        // throw Exception(); // 输出 this is Unknown exception Exception
        // ('this is exception error');
        // num i = 3 / 0;
        int i = 3~/0; // IntegerDivisionByZeroException
        print(i);
      } on Exception catch (e) { //1. 需要指定异常类型时使用on
        print('this is Unknown exception $e');
    
        rethrow;//3. 要部分处理异常,同时允许它继续抛出异常,请使用rethrow关键字,
      //  rethrow 会保留原异常的堆栈信息,而throw里面的堆栈信息会重新定位到最近的点
      // throw e;//这个堆栈信息打印就会只定位到88行。而rethrow会定位到真正错误的点,所以再次
        // 在try-catch里面抛出异常,最好使用rethrow
      } catch (e,s) {
        print('No specified type, handles all error $e');
        print('Stack trace:\n $s');
      }finally{
        print("finally "); // 一定会执行
      }
      //补充:如果有finally,finally代码块一定会执行,
      //所以finally代码块如果有return ,则会覆盖掉try/catch里面的return,
      //这点和java一样
    

    Dart面向对象

    类与对象

    • 构造函数
    • 命名构造函数
    • 常量构造函数
    • 工厂构造函数
    • Getter和Setter
    //dart中的构造函数
    class Point {
      num x;
      num y;
      Point(this.x, this.y);
      // String? name; // Declare instance variable name, initially null.
    // int _age = 0;
    //  2、命名式构造函数——使用初始化列表===>写法:类名.函数名():命名参数
    //   Person.origin(String name,int age):this.name = name,this._age = age;
    //  命名式构造函数的另一种写法
    //     Person.origin(String this.name,int this._age); 
    
    //  3、常量构造函数
    //  使用常量构造函数,要注意两点:一是要确保所有实例变量都是final;
    //  二、构造器前面要有const关键字,且不能要有函数载体
       final String? name; //
       final int _age; //
       const Person(this.name, this._age); 
       //    工厂构造函数
       static Person? instance;
      factory Person.getInstance(){
          if(instance == null){
            instance = Person("name", 31);
          }
          return instance as Person;
      }
    }
    
    

    get和set

    • 这个的好处是可以监听属性值的变换
    class Rect {
      int height;
      int width;
      Rect(this.width, this.height);
      // 手动指定 getter 的写法
      get area {
        return this.height * this.width;
      }
      // 手动指定 setter 的写法
      set h(int value) {
        print("当你调用 xx.h 时,会打印这段话,表示你已经被监听到了");
        this.height = value;
      }
    
      set w(int value) {
        this.width = value;
      }
    }
    
    void main(List args) {
      var p = Rect(10, 20);
      print(p.area);// getter
      p.h = 100;// setter
      p.w = 100;
      print(p.area);
    }
    
    

    静态成员

    Dart泛型

    • 作用:把类型延迟到使用的时候指定
    	show(T a){
    	  print(a);
    	}
    	void main(List args) {
    	 show("hello");//"hello"
    	 //example2
    	 var p = My();
    	  p.say(3);//3
    	}
    	class My{
    	  say(T a){
    		print(a);
    	  }
    	}
    
    

    相关资料

    Dart官网教程
    Dart在线编辑器
    掘金中的Dart相关文章
    掘金中的Dart相关文章2:Dart从入门到放弃
    Dart关键字说明
    flutter1
    flutter2\

  • 相关文章

    服务器端口转发,带你了解服务器端口转发
    服务器开放端口,服务器开放端口的步骤
    产品推荐:7月受欢迎AI容器镜像来了,有Qwen系列大模型镜像
    如何使用 WinGet 下载 Microsoft Store 应用
    百度搜索:蓝易云 – 熟悉ubuntu apt-get命令详解
    百度搜索:蓝易云 – 域名解析成功但ping不通解决方案

    发布评论