美文网首页精华
【转】Flutter 基础语法之Dart语法

【转】Flutter 基础语法之Dart语法

作者: Lins_Do | 来源:发表于2019-09-29 09:40 被阅读0次

    针对当下热门的Flutter跨平台开发语言,Dart语法是其根本,所以这里写了一篇关于Dart语法的文章,希望可以帮到各位快速入门Dart,觉得还不错的朋友麻烦动动手指头给个star支持下,后续会出其他相关的开发教程

    Dart语法一天快速入门篇 (Github发布版本)

    针对当下热门的Flutter跨平台开发语言,Dart语法是其根本,所以这里写了一篇关于Dart语法的文章,希望可以帮到各位快速入门Dart,觉得还不错的朋友麻烦动动手指头给个star支持下原创作教程,后续会出其他更多相关的开发教程

    环境安装篇

    Dart本地环境安装(Mac)

    如果本地还没安装homebrew的,需要先安装: Homebrew 安装地址

    brew tap dart-lang/dart
    brew install dart

    升级版本 brew upgrade dart

    vscode 需要安装 Code runner 和 Dart 两个插件

    类型

    Dart是强大的脚本类语言,可以不定义变量类型使用var字段(类似JavaScript),系统会自动推导该变量类型 好比 var str = 'hello world' 也可以用 String str = 'hello world' , var a = 1和 int a = 1

    常量修饰符final和const

    const表示值不变,并且一开始就需要赋值 final也表示该值不能修改,但可以初始化不赋值,但是只能赋值一次

    示例代码

    final a = new DateTime.now(); print(a);
    const b = new DateTime.now(); print(b);

    数值类型 String bool List Map类型分析

    • String(定义) 可以用三个单引号或者双引号,可以对字符串进行换行调整,输出到控制台还是会按照定义的方式输出,单引号或双引号的不能这么输出

    • String(输出格式,例如str1= 'a', str2= 'b') 可以使用print('str1str2'); 输出结果a b,另一种拼接方式,可以直接用+号,例如 print(str1 + str2)

    • 数值类型包括int,double

    • bool取值true、false (1或者任何非null类型的都为true)

    • List,列表相对来说是支持动态操作的,增(add),删(removeAt),改(list[0]=null),长度(length属性),插入(insert(index, element))

    • List支持定义泛型,例如var list = new List<String>();

    • Map类型,可以直接用var定义,同样支持泛型定义, 例如var map = new Map<String, int>();

    类型判断 is 和 ??= 和isEmpty

    判断是否是某个类型的值, xx is 类型名称

    ??= 如果左边的类型是null ,则将右边的值赋值给左边, 好比 int a; a??=10; a的最终结果就是10

    isEmpty判断字符串是否为空串,如果判断对象是null会报错,例 str.isEmpty(属性不是方法)

    类型转换

    • Number转String使用toString()
    • String转Number使用 parse()

    Dart常用属性以及方法

    属性

    • length
    • reversed (倒序列表,输出对象是元组)
    • isEmpty
    • isNotEmpty
    • keys 获取所有的key值 (主要用在字典上)
    • values 获取所有的value值(主要用在字典上)

    方法

    • toList() 将list对象转List
    • addAll() 拼接数组
    • indexOf() 查到返回索引值,查不到返回-1
    • removeAt() 删除指定索引
    • join() 将列表以特定符号拼接成一个字符串
    • split() 将字符串以特定符号转成list
    • containsValue() 是否包含某个值

    循环方式

    foreach

    示例

      var list = ['1','2', '3'];
      var map = {'name':'zhangsan','age':10};
    
      list.forEach((value){
        print("value is $value");
      });
    
      map.forEach((key,value){
        print("key is $key , value is $value");
      });
    
    

    map

    说明 :对list中的元素统一操作,例如统一加减乘除等

    示例代码

    var li = [1, 3, 5];
    var newLi = li.map((value){
      return value*2;
    });
    print(newLi);
    
    

    where条件

    示例代码

    var li = [1, 3, 5];
    var newLi = li.where((value){
      return value >= 3;
    });
    print(newLi);
    
    

    any条件

    说明:判断是否对象当中有某个条件成立即返回true,好比列表中大于6的元素是否存在

    示例代码

    var li = [1, 3, 5];
    var flag = li.any((value){
      return value >=6;
    });
    print(flag);
    
    

    函数

    注意:函数的形参可以不指定类型,返回值也是可以不指定的,但是为了规范写法,一般还是带上特定的类型做修饰,例如无返回使用关键字 void,形参用强类型限定防止外部参数传入任意类型导致出错。

    • 可选参数 printInfo(String username, [int age]); 可选参数一般放最后

    • 默认参数 printInfo(String username, [sex='男']);

    • 将方法作为参数传给函数(其实也类似与匿名函数,参考代码片段二)

    代码片段1

    
    void fn(){
      print('fn invoke');
    }
    
    void fn2(fnName) {
      fnName();
    }
    
    main() {
      fn2(fn);
    }
    
    

    代码片段2

    var fn = (){
      print('hello world');
    };
    
    main() {
      fn();
    }
    
    
    • 如果函数的方法体只有一句代码,可以用=>代替花括号,以下例子用forEach,例如:
    main() { 
      var list = ['zhangsan', 'lisi', 'wangwu'];
      list.forEach((value)=>print(value));
    }
    
    

    自执行函数

    说明:实际为匿名函数自己调用

      ((){
        print('123');
      })();
    
    

    闭包

    特点:能使变量常住内存并且不会污染全局,既有全局变量的特点也有局部变量的特点

    main() {
      func(){
        int a=100;
        return (){
          a++;
          print(a++);
        };
      }
    
      var func2 = func();
      func2();
      func2();
      func2(); 
    }
    
    

    初始化声明

    可以在生成对象的同时初始化内部参数,如下代码片段:

    
    class Rect {
      int width;
      int height;
    
      //初始化参数
      Rect():width=10,height=10{}
    
      get area {
        return this.width * this.height;
      }
    
      set areaWidth(int width) {
        this.width  = width;
      }
    
    }
    
    main() {
      Rect rect = new Rect();
      print(rect.area);
    }
    
    

    Flutter中生成对象通常会省略new关键字,如下代码片段

    var rect = Rect();
    
    //类似flutter中返回widget
    return Center();//此处省略了new关键字
    
    

    默认构造函数

    默认构造函数跟类名一致,如下代码片段:

    class Person{
      String name;
      int age;
    
      //默认构造函数(只能存在一个默认构造函数)
      Person(String name, int age) {
        this.name = name;
        this.age  = age;
      }
    }
    
    

    以上代码可以简写为如下:

    class Person{
      String name;
      int age;
    
      //默认构造函数(只能存在一个默认构造函数)
      // Person(String name, int age) {
      //   this.name = name;
      //   this.age  = age;
      // }
    
      //默认构造函数简写
      Person(this.name, this.age);
    }
    
    

    命名构造函数

    一个类写多个命名构造函数,写法如下:

    class Person{
      String name;
      int age;
    
      Person.now(String name, int  age) {
        this.name = name;
        this.age  = age;
      }
    
      Person.now2(String name, int  age) {
        this.name = name;
        this.age  = age;
      }
    }
    
    main() {
      Person p = new Person.now('zhangsan', 10);
      Person p2 = new  Person.now2('lisi', 11);
    }
    
    

    类内部的函数中访问类属性

    class Person{
      String name;
      int age;
    
      void printInfo(){
        //通过${this.xxx}
        print('${this.name} , ${this.age}');
    
        //通过this.xxx
        print(this.name);
    
        //通过$name
        print('$name');
      }
    }
    
    

    对象操作符

    • ?条件运算符(如果为空,后续操作不执行,例如p为null,调用getInfo方法,政策执行会报错,如果加上p?.getInfo()就不会调用了),示例代码如下:
    var p;
    
    //这里调用报错,因为p为null
    p.getInfo();
    
    //进行非空判断,不会执行getInfo方法 
    p?.getInfo();
    
    
    • as 类型转换

    示例代码

    class Person {
      Person(){}
    
      void printInfo(){
        print("person test");
      }
    }
    
    main(){
      var p;
      p = '';
      p = new Person();
    
      (p as Person).printInfo();
    
    }
    
    
    • is 类型判断(参考以上【类型】章节的讲解第三点)

    • .. 级联操作(连缀,这种语法类似于链式方式)

    class Person {
      String name;
      int age;
      Person(){}
    
      void printInfo(){
        print("person test");
      }
    }
    
    main(){
      Person p = new Person();
      p..name = 'zhangsan'
       ..age  =  10
       ..printInfo();
    }
    
    

    继承

    关键字extends

    例如 class Teacher extends Person{} 表示Teacher类继承自Person类

    调用父类默认的方法 super

    class Teacher extends Person {
        //此方式调用父类的默认构造方法
        Teacher(String name, int age): super(name,  age);
    }
    
    

    重写父类方法 @override(可以不加,但是一般会加上)

     class Person {
      void printInfo(){
        print("person test");
      }
    }
    
    class Teacher extends Person{
    
      //采用关键字@override 标记该方法是重写父类的,这点跟Java一样
      @override
      void printInfo() {
        super.printInfo();
      }
    }
    
    

    抽象类

    Dart中的抽象类主要用于定义标准,这个跟Java语言有点像,在Dart中,抽象类也可以作为抽象类接口来使用, 抽象类通过关键字 abstract来定义,如果想作为接口来使用定义一套标准,可以用关键字 implements来使用

    抽象方法

    • Dart中,抽象方法不能用abstract来修饰,抽象类中没有方法体的方法我们可以称之为抽象方法
    • 如果子类继承抽象的父类就必须实现里面的所有抽象方法(也可以说是重写所有父类抽象方法,这里记得是抽象方法,抽象类可以存在非抽象方法)
    • 如果把抽象类作为接口来使用,就必须实现所有抽象类里面定义的所有属性与方法
    • 抽象类不能直接被实例化,只要子类才可以
    • 接口更多用于约束和规范,而抽象类更多用于共用某些方法

    示例代码

    //抽象类 继承的子类必须实现抽象方法
    abstract class A {
      printA();
    
      printAA(){
        print("AA");
      }
    }
    
    //接口 实现该接口必须实现 方法+属性
    abstract class B {
      String name;
      printB();
    }
    
    class C extends A implements B {
      @override
      String name;
    
      @override
      printA() {
        print('A');
      }
    
      @override
      printB() {
        print('B');
      }
    }
    
    

    mixins

    Dart中有一种方式能实现类似多继承,但实际不是继承,用关键字with

    示例代码

    class A {
      void printA(){
    
      }
    
      void getStr(){
        print("this is A method");
      }
    }
    
    class B {
      void printB(){
    
      }
    
      void getStr(){
        print("this is B method");
      }
    }
    
    class C with A, B {
      @override
      void printA() {
        print("重写的A方法");
      }
    
      @override
      void printB() {
        print("重写的B方法");
      }
    }
    
    void main() {
      C c = new C();
      c.printA();
      c.printB();
    
      //A和B均有getStr 方法,调用哪个方法取决于with之后写的顺序有关,最后一个会覆盖前面所有的
      c.getStr();  
    
      print(c is A);  //true 
      print(c is B);  //true
    }
    
    

    访问修饰符

    私有属性和方法

    Dart中没有像Java语言中有public,private,protected这些访问修饰符,但是我们可以采用下划线_ 把一个属性或者方法定义成私有的,这一点跟Python的语法很像,但是应该注意的一点,当把该声明了私有方法或属性单独抽离为一个文件时,才生效,好比把Person类放在model目录下,然后其他文件引用了这个model,才变成不能访问的私有属性和方法

    getter和setter修饰符

    以下是最原始的代码片段:

    
    class Rect {
      int width;
      int height;
    
      Rect(this.width,  this.height);
    
      // 简单地求面积
      int area() {
        return this.width * this.height;
      }
    
    }
    
    main() {
      Rect rect = new Rect(10, 2);
      print(rect.area());
    }
    
    

    get 关键字修饰

    
    class Rect {
      int width;
      int height;
    
      Rect(this.width,  this.height);
    
      // 简单地求面积 通过添加get修饰符,可以把area函数变为属性的访问方式
      get area {
        return this.width * this.height;
      }
    
    }
    
    main() {
      Rect rect = new Rect(10, 2);
    
      //这里通过属性的访问方式调用方法 
      print(rect.area);
    }
    
    

    set 关键字修饰

    
    class Rect {
      int width;
      int height;
    
      Rect(this.width,  this.height);
    
      // 简单地求面积 通过添加get修饰符,可以把area函数变为属性的访问方式
      get area {
        return this.width * this.height;
      }
    
      set areaWidth(int width) {
        this.width  = width;
      }
    
    }
    
    main() {
      Rect rect = new Rect(10, 2);
      rect.areaWidth = 100;
      //这里通过属性的访问方式调用方法 
      print(rect.area);
    }
    
    

    static

    ① 说明: 通过static修饰的属性和方法,外部可以通过类名直接调用,例如: Person.name Person.getInfo()

    ② static修饰的方法不能访问非static修饰的属性

    泛型

    说明:泛型是对类型的限定,例如List这样就只能传入字符串类型的数据,List这样只能传入int类型的数据

    示例代码

    main() {
      //可以用var也行
      List<String> list = new List<String>();
      list.add('hello');
      list.add('world');
    
      //以下这行代码报错
      list.add(1);
    
      print(list);
    }
    
    

    Map类型指定泛型的如下

    main() {
      var map = new Map<String, int>();
      map.addAll({'no':1});
    
      //以下这行代码报错
      map.addAll({'username':'zhangsan'});
    
      print(map);
    }
    
    

    修饰方法

    说明:修饰方法可以不对类型进行强制检查,能提高函数的复用性

    示例代码

    
    T returnValue<T>(T value) {
      return value;
    }
    
    main() {
      String name = returnValue('zhangsan');
      int age = returnValue(10);
    
      print('$name  $age');
    }
    
    

    自定义List泛型输入

    
    class JSList<T> {
      var list = new List<T>();
    
      add(T value) {
        this.list.add(value);
      }
    }
    
    main() {
      var list = JSList<String>();
      list.add('helloworld');
    
      //以下这行代码报错,因为JSList限定了输入类型
      list.add(123);
    }
    
    

    泛型配合接口实现

    
    abstract class A<T> {
      printInfo(T value);
    }
    
    class B<T> implements A<T> {
      @override
      printInfo(T value) {
        print('这是B的输出类型');
      }
    }
    
    class C<T> implements A<T> {
      @override
      printInfo(T value) {
        print('这是C的输出类型');
      }
    }
    
    main() {
      var b = new B<String>();
      var c = new C<int>();
    
      b.printInfo('hello world');
      c.printInfo(123);
    }
    
    

    相关文章

      网友评论

        本文标题:【转】Flutter 基础语法之Dart语法

        本文链接:https://www.haomeiwen.com/subject/reaxpctx.html