美文网首页flutter
Dart 关键字【2】

Dart 关键字【2】

作者: _兜兜转转_ | 来源:发表于2020-09-07 14:24 被阅读0次

    想要写好Flutter,那么对Dart的基本关键字的掌握是必不可少的,今天就再探究一下其他的关键字。

    as is si!

    as is is!,运算符用于运行时处理类型检查:

    obj实现了T的接口时,obj is Ttrue,obj as T可以将obj类型转换成T类型:

    
    class Person {
      void play(){
        print('person');
      }
    }
    class PersonSub extends Person{}
    class Person2 {
        void play(){
        print('person2');
      }
    }
    
     Person person = PersonSub();
     if(person is Person2){
     (person as Person2).play();
     }
     if(person is PersonSub){
       (person as PersonSub).play();
     }
    

    person类型是Person2执行第一个if函数,如果直接(person as Person2).play();,则会崩溃,每次转换类型的时候,提交校验a is T是有必要的。

    enum

    枚举类型也称为 enumerationsenums , 是一种特殊的类,用于表示数量固定的常量值。

    throw catch on final rethrow

    捕获异常可以避免异常继续传递(除非重新抛出(rethrow )异常)。 可以通过捕获异常的机会来处理该异常:

    try {
      breedMoreLlamas();
    } on OutOfLlamasException {
      buyMoreLlamas();
    }
    

    通过指定多个 catch 语句,可以处理可能抛出多种类型异常的代码。 与抛出异常类型匹配的第一个 catch 语句处理异常。 如果 catch 语句未指定类型, 则该语句可以处理任何类型的抛出对象:

    try {
      breedMoreLlamas();
    } on OutOfLlamasException {
      // 一个特殊的异常
      buyMoreLlamas();
    } on Exception catch (e) {
      // 其他任何异常
      print('Unknown exception: $e');
    } catch (e) {
      // 没有指定的类型,处理所有异常
      print('Something really unknown: $e');
    }
    

    如上述代码所示,捕获语句中可以同时使用 oncatch ,也可以单独分开使用。 使用 on 来指定异常类型, 使用 catch 来 捕获异常对象。

    catch() 函数可以指定1到2个参数, 第一个参数为抛出的异常对象, 第二个为堆栈信息 ( 一个 StackTrace 对象 )。

    try {
      // ···
    } on Exception catch (e) {
      print('Exception details:\n $e');
    } catch (e, s) {
      print('Exception details:\n $e');
      print('Stack trace:\n $s');
    }
    

    如果仅需要部分处理异常, 那么可以使用关键字 rethrow 将异常重新抛出。

    void misbehave() {
      try {
        dynamic foo = true;
        print(foo++); // Runtime error
      } catch (e) {
        print('misbehave() partially handled ${e.runtimeType}.');
        rethrow; // Allow callers to see the exception.
      }
    }
    
    void main() {
      try {
        misbehave();
      } catch (e) {
        print('main() finished handling ${e.runtimeType}.');
      }
    }
    

    不管是否抛出异常,finally 中的代码都会被执行。 如果 catch 没有匹配到异常, 异常会在 finally 执行完成后,再次被抛出:

    try {
      breedMoreLlamas();
    } finally {
      // Always clean up, even if an exception is thrown.
      cleanLlamaStalls();
    }
    

    任何匹配的 catch 执行完成后,再执行 finally

    try {
      breedMoreLlamas();
    } catch (e) {
      print('Error: $e'); // Handle the exception first.
    } finally {
      cleanLlamaStalls(); // Then clean up.
    }
    

    factory

    当执行构造函数并不总是创建这个类的一个新实例时,则使用 factory 关键字。 例如,一个工厂构造函数可能会返回一个 cache 中的实例, 或者可能返回一个子类的实例。

    以下示例演示了从缓存中返回对象的工厂构造函数:

    class Logger {
      final String name;
      bool mute = false;
    
      // 从命名的 _ 可以知,
      // _cache 是私有属性。
      static final Map<String, Logger> _cache =
          <String, Logger>{};
    
      factory Logger(String name) {
        if (_cache.containsKey(name)) {
          return _cache[name];
        } else {
          final logger = Logger._internal(name);
          _cache[name] = logger;
          return logger;
        }
      }
    
      Logger._internal(this.name);
    
      void log(String msg) {
        if (!mute) print(msg);
      }
    }
    

    const

    使用过程中从来不会被修改的变量, 可以使用 final 或 const, 而不是 var 或者其他类型, Final 变量的值只能被设置一次; Const 变量在编译时就已经固定 (Const 变量 是隐式 Final 的类型.) 最高级 final 变量或类变量在第一次使用时被初始化。

    提示: 实例变量可以是 final 类型但不能是 const 类型。 必须在构造函数体执行之前初始化 final 实例变量 —— 在变量声明中,参数构造函数中或构造函数的初始化列表中进行初始化。

    创建和设置一个 Final 变量:

    final name = 'Bob'; // Without a type annotation
    final String nickname = 'Bobby';
    

    final 不能被修改:

    name = 'Alice'; // Error: 一个 final 变量只能被设置一次。
    

    如果需要在编译时就固定变量的值,可以使用 const 类型变量。 如果 Const 变量是类级别的,需要标记为 static const。 在这些地方可以使用在编译时就已经固定不变的值,字面量的数字和字符串, 固定的变量,或者是用于计算的固定数字:

    const bar = 1000000; // 压力单位 (dynes/cm2)
    const double atm = 1.01325 * bar; // 标准气压
    

    operator

    重写运算符,下面的运算符可以被重写。

    < + | []
    > / ^ [] =
    <= ~/ & ~
    >= * << ==
    % >>

    提示: 你可能会被提示 != 运算符为非可重载运算符。 因为 e1 != e2 表达式仅仅是 !(e1 == e2) 的语法糖。

    下面示例演示一个类重写 + 和 - 操作符:

    class Vector {
      final int x, y;
    
      Vector(this.x, this.y);
    
      Vector operator +(Vector v) => Vector(x + v.x, y + v.y);
      Vector operator -(Vector v) => Vector(x - v.x, y - v.y);
    
      // 运算符 == 和 hashCode 部分没有列出。 有关详情,请参考下面的注释。
      // ···
    }
    
    void main() {
      final v = Vector(2, 3);
      final w = Vector(2, 2);
    
      assert(v + w == Vector(4, 5));
      assert(v - w == Vector(0, 1));
    }
    

    如果要重写 == 操作符,需要重写对象的 hashCode getter 方法。 重写 == 和 hashCode 的实例,参考 Implementing map keys.

    part part of

    covariant

    Function

    Dart 是一门真正面向对象的语言, 甚至其中的函数也是对象,并且有它的类型 Function 。 这也意味着函数可以被赋值给变量或者作为参数传递给其他函数。 也可以把 Dart 类的实例当做方法来调用。 有关更多信息,参考 Callable classes.

    已下是函数实现的示例:

    bool isNoble(int atomicNumber) {
      return _nobleGases[atomicNumber] != null;
    }
    

    虽然在 Effective Dart 中推荐 公共API中声明类型, 但是省略了类型声明,函数依旧是可以正常使用的:

    isNoble(atomicNumber) {
      return _nobleGases[atomicNumber] != null;
    }
    

    如果函数中只有一句表达式,可以使用简写语法:

    bool isNoble(int atomicNumber) => _nobleGases[atomicNumber] != null;
    => expr 语法是 { return expr; } 的简写。 => 符号 有时也被称为 箭头 语法。

    提示: 在箭头 (=>) 和分号 (;) 之间只能使用一个 表达式 ,不能是 语句 。 例如:不能使用 if 语句 ,但是可以是用 条件表达式.

    with

    default

    return yield

    deferred hide

    延迟加载库
    Deferred loading (也称之为 lazy loading) 可以让应用在需要的时候再加载库。 下面是一些使用延迟加载库的场景:

    • 减少 APP 的启动时间。
    • 执行 A/B 测试,例如 尝试各种算法的 不同实现。
    • 加载很少使用的功能,例如可选的屏幕和对话框。

    要延迟加载一个库,需要先使用 deferred as 来导入:

    import 'package:greetings/hello.dart' deferred as hello;
    

    当需要使用的时候,使用库标识符调用 loadLibrary() 函数来加载库:

    Future greet() async {
      await hello.loadLibrary();
      hello.printGreeting();
    }
    

    在一个库上你可以多次调用 loadLibrary() 函数。但是该库只是载入一次。

    使用延迟加载库的时候,请注意一下问题:

    延迟加载库的常量在导入的时候是不可用的。 只有当库加载完毕的时候,库中常量才可以使用。
    在导入文件的时候无法使用延迟库中的类型。 如果你需要使用类型,则考虑把接口类型移动到另外一个库中, 让两个库都分别导入这个接口库。
    Dart 隐含的把 loadLibrary() 函数导入到使用 deferred as 的命名空间 中。 loadLibrary() 方法返回一个 Future。

    show hide

    导入库的一部分
    如果你只使用库的一部分功能,则可以选择需要导入的 内容。例如:

    // Import only foo.
    import 'package:lib1/lib1.dart' show foo;
    
    // Import all names EXCEPT foo.
    import 'package:lib2/lib2.dart' hide foo;
    

    参考

    相关文章

      网友评论

        本文标题:Dart 关键字【2】

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