美文网首页
dart 基础

dart 基础

作者: Maj_sunshine | 来源:发表于2019-12-17 14:20 被阅读0次

    语言特性

    • 在Dart中,一切都是对象,一切对象都是class的实例,哪怕是数字类型、方法甚至null都是对象,所有的对象都是继承自Object
    • 尽管 Dart 是强类型语言,但是在声明变量时指定类型是可选的,因为 Dart 可以进行类型推断。
    • Dart 支持泛型,比如 List<int>(表示一组由 int 对象组成的列表)或 List<dynamic>(表示一组由任何类型对象组成的列表)。
    // 声明数组,里面包含< DeviceHealthModel >
    List<DeviceHealthModel> dataSource = [];
    
    • 跟Java不同的是,Dart没有public protected private等关键字,如果某个变量以下划线(_)开头,代表这个变量在库中是私有的
    • Dart中变量可以以字母或下划线开头,后面跟着任意组合的字符或数字

    变量和常量

    • 创建变量
       var age = 19; // 类型推断为int
       dynamic name1 = '小菊'; // 未知类型
       String name2 = '小菊'; // 指定类型为String
       List<int> ages = [1, 2, 3, 4]; // 声明int数组
       int myage; // 未初始化的变量, 默认值为null
    
    • 创建常量 final和const

    • 如果一个变量的值不再修改,则使用final或者const代替var
      一个final变量只能赋值一次;一个const变量是编译时常量,const变量默认为final变量。
      final修饰的顶级变量或类变量在第一次声明的时候就需要初始化。

    void main(List<String> args) {
     final String name = "小菊";
      const age = 18; // 声明时必须初始化, 否则报错 The constant 'age' must be initialized.
      //  The name 'deviceName' is already defined.
     }
    
    • 顶层final变量与类变量在首次访问时执行初始化。需要注意的是,实例变量可以为final,但是不能是const
    class DeviceHealth extends StatefulWidget {
      @override
      final a ; // final修饰的实例变量可以在下面初始化的时候赋值
    
      static const b = ""; //  常量如果是类里的,请使用 static const
    
      DeviceHealth({
        this.a = "",
        // this.a = "a", // 无法二次修改
        GlobalKey<_DeviceHealthState> key,
      }) : super(key: key);
    
      State<StatefulWidget> createState() {
        // TODO: implement createState
        return null;
      }
    }
    
    class _DeviceHealthState extends State<DeviceHealth> {
      @override
      Widget build(BuildContext context) {
        // TODO: implement build
        throw UnimplementedError();
      }
    }
    
    • const 关键字不仅仅可以用来定义常量,还可以用来创建常量值,该常量值可以赋予给任何变量
    void main(List<String> args) {
      var a = const [1, 2]; // const创建 常量列表
      a = [2]; // 可以被重新赋值
    
      final b = const [1, 2]; 
      b = [2]; // final 和 const定义 还是不可以被重新赋值
     }
    
    • const 只能被赋值const类型, 无法被final 或其他类型赋值.

    数据类型

    • numbers
      Dart支持两种类型的数字
    void main(List<String> args) {
      var a = 1; // int
      var b = 1.0; // double
      int c = int.parse("1"); // string 转 int 
      double d = double.parse("1.1"); // string 转 double 
    
      String str1 = 1.toString(); // 数字转字符串
      String str2 = 3.1415926.toStringAsFixed(2); // 输出3.14
     }
    
    • String
    void main(List<String> args) {
      String str1 = "sdhsadkjhas"; // 创建字符串
      String str2 = "fnjdshuic\""; //  \用于转义
      print("字符串1为 $str1"); // $ 格式化
      print("字符串2为 ${str1 + str2}"); // ${} 插入表达式 , + 拼接字符串
      String str3 = '''
         创建多行字符串 
       ''';
      print(str1.length); // 字符串长度
      print(str1.isEmpty); // 字符串是否为空
      str1.contains("sss"); // 字符串是否包含另外一个字符串
      String str4 = str1.substring(1,4); // 字符串截取
      bool a = str4.startsWith("s"); // 字符串是否以xxx开头
      int b = str4.indexOf("sss"); // 第一次某个字符串的下标
      int c = str4.lastIndexOf("sss"); // 最后一次出现某个字符串的下标
      str4.toLowerCase(); // 字符串转小写
      str4.toUpperCase(); // 字符串转大写
      str4.trim(); // 字符串清除空格
      str4.trimLeft(); // 清除最左边的空格
      str4.trimRight(); // 清除最右边的空格
      List strList = str4.split("."); // 字符串分割后数组
    
      str4.replaceAll(new RegExp(r'e'), 'é'); // 字符串替换
      str4.replaceAll("a", "s");
     }
    
    • booleans
     true 和 false
    
    • list
    void main(List<String> args) {
      List list = [10, 7, 23]; //创建一个int类型的list
      var animal = new List();
      animal.add('dog'); // 添加
      animal.addAll(['cat', 'cat']); // 从另外一个数组添加多个
      print(animal.length); // 获取List的长度
      print(animal.first); // 第一个
      print(animal.last); // 最后一个
      print(animal[0]); // 索引获取
      print(animal.indexOf('cat')); // 查找某个元素的索引
      print(animal.removeAt(0)); // 删除指定位置,返回删除的元素
      animal.remove('cat'); // 删除指定元素,成功返回true,失败返回false, 如果集合里面有多个, 只会删除集合中第一个改元素
      animal.removeLast(); // 删除最后一个,返回删除的元素
      animal.removeRange(0, 2); // 删除 [0, 2) 内元素
      animal.removeWhere((item) => item.length > 3); // 删除指定条件的元素(这里是元素长度大于3)
      animal.clear(); // 删除所有
      animal.sort(); // 按照ASCII码排序
      animal.sublist(1,3); // 获取子数组[) 左开右闭
    } 
    
    • map
    void main(List<String> args) {
      Map<String, String> animal1 = {}; // 创建空map
      var animal2 = new Map<String, String>(); // 创建空map
    
      // 如果Key 不存在于 Map 中 取值则会返回一个 null
    
      animal1["a"] = "1"; // 赋值
      animal1.remove("a"); // 移除
      animal1.containsKey("a"); // 是否存在某个key
      animal1.containsValue("b"); // 是否存在某个value
      print(animal1.keys); // 打印所有的key
      print(animal1.values); // 打印所有的value
      animal1.clear(); // 清空map
      animal1.isEmpty; // 检测是否为空
      animal1.addAll({"c": "2", "d" : "3"}); // 从另外一个map 添加
    } 
    
    

    运算符 operators

    描述 操作符
    一元后缀 expr++ expr-- () [] . ?.
    一元前缀 expr !expr ~expr ++expr --expr
    乘除法 * / % ~/
    加减法 + -
    位运算 << >>
    按位与 &
    按位或 |
    按位异或 ^
    逻辑与 &&
    逻辑或 ||
    关系和类型测试 >= > <= < as is is!
    相等判断 == !=
    空判断 ??
    条件表达式 expr1 ? expr2 : expr3
    赋值 = *= /= ~/= %= += -= <<= >>= &= ^= = ??=
    级联 ..
    • 挑一些区别性的
    操作符 作用
    is 判断一个变量是不是某个类型的数据
    is! 判断变量不是某个类型的数据
    as 强制转换
    / 除法, 可能带小数点
    ~/ 是取整运算符
    ??= 如果 ??= 运算符前面的变量为null,则赋值,否则不赋值
    .. 同一个对象上连续调用多个对象的变量或方法
    • is, is!
      (判断一个变量是不是某个类型的数据)
      String a = "1";
      print(a is String); // true
      print(a is! String); // false 
    
    • as
      (强制转换)
      dynamic b = 1; // 未知类型
      print(b as int); // 强制转换int
    
    • /
      (除法, 可能带小数点)
    var a = 100.0;
    a = a / 2;
    print(a); // 50.0
    
    • ~/
      (取整)
      var a = 100.0;
      int c = a ~/ 3; // 必须用int 接收
      print(c); // 33
    
    • ??=
      (如果 ??= 运算符前面的变量为null,则赋值,否则不赋值)
      var str1 = "小菊";
      String str2;
      str1 ??= "孝举"; // 小菊
      str2 ??= "孝举"; // 孝举
      print(str1);
      print(str2);
    
    • ..
      (同一个对象上连续调用多个对象的变量或方法)
     void main() {
      var str1 = "小菊";
      str1.toLowerCase()..replaceAll("s", "ss"); // 连续调用多个对象方法.
    }
    

    控制流程语句

    • if else
      Dartif语句中的条件必须是一个布尔值,不能是其它类型. (iOS中也可以用整型表示, 这里不行)
      if (3 > 1) {
        print("大");
      } else {
        print("小");
      }
    
    • for 循环
    1. 标准for循环(可以使用)
    for (var i = 0; i < 5; i++) {
      print(" $i");
    }
    
    1. for-in 循环

    数组遍历

        var numbers = [1,2,3,4,5];
        for (var number in numbers) {
          print(number);
        }
    
    1. for-each
      数组遍历
    var numbers = [1,2,3,4,5];
    numbers.forEach((number) =>  
           print(numbers)
    );
    

    字典 key-value遍历, 请使用forEach.

        var numbers = {"a": "1", "b": "2"};
        numbers.forEach((key, value) => {
          print(value),
          print(key),
        });
    
    • while 和 do-while 循环 (和原生语言一样)
    • break 和 continue (和原生语言一样)
    • switch 和 case
    void main() {
        int a = 1;
        switch (a) {
        mark:
        case 0:
          print("0");
          break;
        case 1:
          print("1");
          continue mark; // Continue使用在被标记为mark的子句中
        case 2:
          print("2");
          break;
      }
    }
    
    // 输出1  0
    

    异常 Exceptions

    try {
      breedMoreLlamas();
    } on OutOfLlamasException {
      // 指定异常
      buyMoreLlamas();
    } on Exception catch (e) {
      // 其它类型的异常
      print('Unknown exception: $e');
    } catch (e) {
      // // 不指定类型,处理其它全部
      print('Something really unknown: $e');
    }
    

    函数 Function

    类 Class

    • 类的基本构成
      构造方法和实例变量
      类定义中所有的变量, Dart语言都会隐式的定义 setter 方法,针对非空的变量会额外增加 getter 方法。
    typedef void ReConnectButtonClick();
    
    class ReConnectWifiView extends StatefulWidget {
      String deviceName; // 实例变量
      ReConnectButtonClick reConnectButtonClick; // 实例变量
    
    // 初始化方法1
      ReConnectWifiView({
        this.deviceName = "",
        this.reConnectButtonClick,
        GlobalKey<_ReConnectWifiViewState> key,
      }) : super(key: key);
    
      // iOS方式的初始化方法2, 不推荐 扩展性差) 等同于下面的初始化3
      // ReConnectWifiView(this.deviceName, this.reConnectButtonClick);
    
     // iOS方式的初始化方法3, 不推荐 扩展性差)
      // ReConnectWifiView(String deviceName, ReConnectButtonClick reConnectButtonClick) {
      //   this.deviceName = deviceName;
      //   this.reConnectButtonClick = reConnectButtonClick;
      // }
    
      // 命名式构造函数
      // ReConnectWifiView.method1(String deviceName, ReConnectButtonClick reConnectButtonClick) {
      //   this.deviceName = deviceName;
      //   this.reConnectButtonClick = reConnectButtonClick;
      // }
    
      @override
      State<StatefulWidget> createState() {
        // TODO: implement createState
        return new _ReConnectWifiViewState();
      }
    }
    class _ReConnectWifiViewState extends State<ReConnectWifiView> {
       @override
      Widget build(BuildContext context) {
        // TODO: implement build
        throw UnimplementedError();
      }
    }
    
    • 获取对象的类型
      可以使用Object对象的runtimeType属性在运行时获取一个对象的类型
    void main() {
        int a = 1;
        print("这个类型是 ${a.runtimeType}");
    }
    
    输出: 这个类型是 int
    
    • 静态变量&&静态方法
     class Mine  {
       @override  
    
       static const money = 17; // 定义静态变量, 在其首次被使用的时候才被初始化。
       static String sayHello() {
         return "hello";
       }
     }
    
     class You {
       _say() {
         Mine.sayHello(); // Mine类调用方法
       }
     }
    
    • 继承(extends)
      Dart 语言中,子类不会继承父类的命名构造函数。如果不显式提供子类的构造函数,系统就提供默认的构造函数
      如果想要子类也拥有一个父类一样名字的构造函数,必须在子类是实现这个构造函数。
    class Person {
      String firstName;
    
      Person.fromJson(Map data) {
        print('in Person');
      }
    }
    
    由于Employee类没有默认构造方法,只有一个命名构造方法fromJson,所以在Employee类继承Person类时,
    需要调用父类的fromJson方法做初始化,
    而且必须使用Employee.fromJson(Map data) : super.fromJson(data)这种写法,
    
    class Employee extends Person {
      Employee.fromJson(Map data) : super.fromJson(data) {
        print('in Employee');
      }
    }
    
    • set get 方法
    class ReConnectWifiView extends StatefulWidget {
      String deviceName;
      ReConnectButtonClick reConnectButtonClick;
    
      ReConnectWifiView({
        this.deviceName = "",
        this.reConnectButtonClick,
        GlobalKey<_ReConnectWifiViewState> key,
      }) : super(key: key);
    
    // set方法
      set xiaojuName(String value) {
        deviceName = value + deviceName;
      }
    // get 方法
      String get myName {
        return deviceName + "";
      }
    
      @override
      State<StatefulWidget> createState() {
        // TODO: implement createState
        return new _ReConnectWifiViewState();
      }
    }
    
    • 类-抽象类
    abstract class Person {
      void work(); // 抽象方法
      void sayhello() { // 普通方法
    
      }
     }
    
     class Me extends Person {
       @override  // 抽象类的子类必须实现抽象方法
       void work() { //  提供一个实现,所以在这里该方法不再是抽象的
      }
     }
    
    • noSuchMethod()
      如果调用了对象上不存在的方法或实例变量将会触发 noSuchMethod 方法,你可以重写noSuchMethod 方法来追踪和记录这一行为
    void main() {
      TestMethod test = new TestMethod();
      dynamic f = test.foo;
      // Invokes `Object.noSuchMethod`, not `TestMethod.noSuchMethod`, so it throws.
      f(42);
    }
    
    class TestMethod {
    // 除非你重写noSuchMethod,否则使用不存在的成员会导致NoSuchMethodError
      @override
      void noSuchMethod(Invocation invocation) {
        print('You tried to use a non-existent member: ' +
            '${invocation.memberName}');
      }
    dynamic foo();
    }
    
    • 类-扩展一个类的方法 Extension (in Dart 2.7)
      当您使用他人的API或实现广泛使用的库时,更改API通常是不切实际或不可能的。 但是您可能仍想添加一些功能。可以使用这个添加方法.
      类似iOS中的类别, 扩张一个类的方法, 不需要加入到class类的代码中.
    
     class Mine  {
       @override  // 抽象类的子类必须实现抽象方法
    
       _extensionTest() {
         this.doneAction();
       }
     }
    
    // 为Mine 这个类扩展方法, MineExtension为扩展类名(随便取), doneAction扩展方法
    extension MineExtension on Mine {
      void doneAction() {
        print("Ssss");
      }
    }
    
    • 枚举
    1. enum
    enum Color { red, green, blue }
    
    1. 和iOS一样, 枚举值默认从0开始, 上面依次为
    Color.red.index == 0
    Color.green.index == 1
    Color.blue.index == 2
    
    1. 获取枚举中所有值的列表
    List<Color> colors = Color.values;
    assert(colors[2] == Color.blue);
    
    • Mixin
      Mixin 是一种在多重继承中复用某个类中代码的方法模式。
    class Dog {
      String name; 
      sayWang() {
        print("说汪汪汪");
      }
    }
    class Cat {
      sayMiao() {
        print("说喵喵喵");
      }
    }
    // 使用with 关键字, 使得person 也能调用Dog, Cat方法和变量
    class Person with Dog, Cat {
      say() {
        Person().sayWang(); // 使用dog方法.
        print(Person().name); // 使用dog变量
        Person().sayMiao();
        print("我也会说汪汪汪, 也会喵喵喵");
      }
    }
    

    库和可见性

    异步支持

    asyncawait关键字用于实现异步编程,并且让你的代码看起来就像是同步的一样。
    await表达式中, 表达式 的值通常是一个 Future 对象;如果不是,那么这个值会自动转为Future

    // 做异步等待, 直到await 返回数据
      Future<void> _receiveCloudedgeData() async {
        dynamic result;
        try {
          result = await WYChannel.mineDataChannel
              .invokeMethod(WYChannel.chimeSettingMethod);
        } on PlatformException {
          result = "error";
        }
        if (result is String) {
          // print(result);
          GlobalConfig.languageCode = result;
        }
    
    import 'dart:async';
    import 'package:http/http.dart' as http;
    // 返回string
    Future<String> getNetData() async{
      http.Response res = await http.get("http://www.baidu.com");
      return res.body;
    }
    
    main() {
      getNetData().then((str) {
        print(str);
      });
    }
    

    相关文章

      网友评论

          本文标题:dart 基础

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