美文网首页
dart语言学习笔记-2

dart语言学习笔记-2

作者: fan_xing | 来源:发表于2019-03-07 20:16 被阅读0次

    默认值

    如果变量未被初始化,变量的值为null

    int lineCount;
    assert(lineCount == null);
    

    注:assert()的调用在生产阶段会被忽略

    赋值

    ??=给空对象赋值

    // Assign value to a
    a = value;
    // Assign value to b if b is null; otherwise, b stays the same
    b ??= value;
    

    final & const

    final变量只能设值一次且需要在第一次使用时设值,const变量为编译期常量(隐式final)

    注:实例变量可以为final,但不能为const。final的实例变量必须在构造器之前初始化,如变量声明、构造参数,或者构造器的初始化列表

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

    const变量的值为数字、字符串,或他们的计算结果

    const bar = 1000000; // Unit of pressure (dynes/cm2)
    const double atm = 1.01325 * bar; // Standard atmosphere
    

    const值

    var foo = const [];
    final bar = const [];
    const baz = []; // Equivalent to `const []`
    

    你可以修改非final,非const的变量,即使他的值为const

    foo = [1, 2, 3]; // Was const []
    

    内建数据类型

    numbers

    只包含int和double类型,且int不大于64bits,double为64bit

    int会自动转为double

    double z = 1; // Equivalent to double z = 1.0.
    

    strings

    Dart的string是一串UTF-16编码的字符,可以用单引号或双引号来创建

    var s1 = 'Single quotes work well for string literals.';
    var s2 = "Double quotes work just as well.";
    var s3 = 'It\'s easy to escape the string delimiter.';
    var s4 = "It's even easier to use the other delimiter.";
    

    如果变量为表达式,可通过${expression}在创建字符串时来引用,如果是变量可以省略{},对象的话会默认调用toString()方法

    var s = 'string interpolation';
    
    assert('Dart has $s, which is very handy.' ==
        'Dart has string interpolation, ' +
            'which is very handy.');
    assert('That deserves all caps. ' +
            '${s.toUpperCase()} is very handy!' ==
        'That deserves all caps. ' +
            'STRING INTERPOLATION is very handy!');
    

    字符串可以通过相邻或者+来拼接

    var s1 = 'String '
        'concatenation'
        " works even over line breaks.";
    assert(s1 ==
        'String concatenation works even over '
        'line breaks.');
    
    var s2 = 'The + operator ' + 'works, as well.';
    assert(s2 == 'The + operator works, as well.');
    

    如果要创建的是多行的字符串(包含换行),用三个引号包裹即可

    var s1 = '''
    You can create
    multi-line strings like this one.
    ''';
    
    var s2 = """This is also a
    multi-line string.""";
    

    如果要创建原始的非转义字符串,需要用r开头(和python相同)

    var s = r'In a raw string, not even \n gets special treatment.';
    

    booleans(true/false)

    Dart为类型安全,所以不能像javascript那样使用if (nonbooleanValue)assert (nonbooleanValue)

    lists

    List代表有序集合,在Dart中的数组即为List对象

    //Dart推断list代表List<int>,如果添加非int型对象会发出异常警告
    var list = [1, 2, 3];
    

    sets

    Set代表无序集合

    //Dart推断set代表Set<String>,只能添加string对象
    var halogens = {'fluorine', 'chlorine', 'bromine', 'iodine', 'astatine'};
    

    创建一个空的set,需要指明类型,如

    var names = <String>{};
    // Set<String> names = {}; // This works, too.
    // var names = {}; // Creates a map of Map<dynamic, dynamic>, not a set.
    

    注:小心创建了一个map对象
    要创建一个编译期的常量,需要添加const前导

    final constantSet =
        const {'fluorine', 'chlorine', 'bromine', 'iodine', 'astatine'};
    // constantSet.add('helium'); // Uncommenting this causes an error.
    

    maps

    两种初始化方式

    //方式1
    var gifts = {
      // Key:    Value
      'first': 'partridge',
      'second': 'turtledoves',
      'fifth': 'golden rings'
    };
    //方式2
    var nobleGases = Map();
    nobleGases[2] = 'helium';
    nobleGases[10] = 'neon';
    nobleGases[18] = 'argon';
    

    构建编译期的常量时,需要添加前导const

    final constantMap = const {
      2: 'helium',
      10: 'neon',
      18: 'argon',
    };
    
    // constantMap[2] = 'Helium'; // Uncommenting this causes an error.
    

    runes

    代表UTF-32编码的字符串

    
    fromCharCodes
    main() {
      var clapping = '\u{1f44f}';
      print(clapping);
      print(clapping.codeUnits);
      print(clapping.runes.toList());
    ​
      Runes input = new Runes(
          '\u2665  \u{1f605}  \u{1f60e}  \u{1f47b}  \u{1f596}  \u{1f44d}');
      print(new String.fromCharCodes(input));
    }
    

    console output

    👏
    [55357, 56399]
    [128079]
    ♥  😅  😎  👻  🖖  👍
    

    当进行字符处理时,需要当心包含runes的情况,如

    void main() {
      //一种情况
      var input = "Music \u{1f44d} for the win"; // Music 👍 for the win
      
      print(input.split('').reversed.join()); // niw eht rof �� cisuM
      
      print(new String.fromCharCodes(input.runes.toList().reversed)); // niw eht rof 👍 cisuM
    
      //另一种情况
      var input2 =  'Ame\u{301}lie'; // Amélie
      print(new String.fromCharCodes(input2.runes.toList().reversed)); // eiĺemA
    }
    

    symbols

    Symbol对象代表声明的运算符或者标识符,你可能永远都不需要Symbol
    通过#跟随标识符获取symbol

    #radix
    #bar
    

    函数对象(Functions)

    箭头表达式

    bool isNoble(int atomicNumber) => _nobleGases[atomicNumber] != null;
    

    注:=> expr;语法是{ return expr; }的简写,在=>之间只能是表达式,不能是其他如if

    可选参数

    Optional positional parameters

    必选参数在前,可选参数在后

    String say(String from, String msg, [String device]) {
      var result = '$from says $msg';
      if (device != null) {
        result = '$result with a $device';
      }
      return result;
    }
    
    assert(say('Bob', 'Howdy') == 'Bob says Howdy');
    

    Optional named parameters

    通过{param1, param2, ...}的格式命名参数,用@required标记为必选参数,通过参数名称传值( 即paramName: value)方式调用

    /// Sets the [bold] and [hidden] flags ...
    void enableFlags({bool bold, @required bool hidden}) {...}
    //使用时
    enableFlags(bold: true, hidden: false);
    

    参数默认值

    定义时通过=赋值,且默认值必须是编译期常量,未赋值默认为null

    /// Sets the [bold] and [hidden] flags ...
    void enableFlags({bool bold = false, bool hidden = false}) {...}
    
    // bold will be true; hidden will be false.
    enableFlags(bold: true);
    

    main函数

    任何app都必须包括一个顶级的main(),作为app的入口函数,main()必须返回void,并有一个可选的List<String>参数。

    void main() {
      querySelector('#sample_text_id')
        ..text = 'Click me!'
        ..onClick.listen(reverseText);
    }
    

    ..语法是作为级联调用的

    匿名函数

    格式
    ([[Type] param1[, …]]) {
    codeBlock;
    };

    var list = ['apples', 'bananas', 'oranges'];
    list.forEach((item) {
      print('${list.indexOf(item)}: $item');
    });
    

    如果函数体只有一条语句,可以用箭头语法替换

    list.forEach(
        (item) => print('${list.indexOf(item)}: $item'));
    

    Lexical scope(词法范围)

    Dart是一种词汇范围的语言,这意味着变量的范围是静态确定的,只需通过代码的布局。您可以“沿大括号向外”查看变量是否在范围内。

    bool topLevel = true;
    
    void main() {
      var insideMain = true;
    
      void myFunction() {
        var insideFunction = true;
    
        void nestedFunction() {
          var insideNestedFunction = true;
    
          assert(topLevel);
          assert(insideMain);
          assert(insideFunction);
          assert(insideNestedFunction);
        }
      }
    }
    

    Lexical closures(词法闭包)

    closure(闭包)可以访问他所在的lexical scope(词法范围)的变量,即使被用到了在他原有的范围之外

    /// Returns a function that adds [addBy] to the
    /// function's argument.
    Function makeAdder(num addBy) {
      return (num i) => addBy + i;
    }
    
    void main() {
      // Create a function that adds 2.
      var add2 = makeAdder(2);
    
      // Create a function that adds 4.
      var add4 = makeAdder(4);
    
      assert(add2(3) == 5);
      assert(add4(3) == 7);
    }
    

    特殊运算符

    condition ? expr1 : expr2

    如果condition为true,则调用expr1,否则调用expr2

    expr1 ?? expr2

    如果expr1非空,返回expr1的值,否则返回expr2的值

    Cascade notation (..)

    用前一个对象作为级联对象

    final addressBook = (AddressBookBuilder()
          ..name = 'jenny'
          ..email = 'jenny@example.com'
          ..phone = (PhoneNumberBuilder()
                ..number = '415-555-0100'
                ..label = 'home')
              .build())
        .build();
    

    ?.

    .运算符类似,如foo?.bar,如果foo非空,返回foo.bar,否则返回null

    控制语句

    switch and case

    switch语句可以比较integer,string,或者用==比较编译期常量。待比较的对象必须是同一个类(不能为子类),并且这个类不能复写了==。枚举类适合switch语句。

    注:某些情况下break不可缺少

    var command = 'OPEN';
    switch (command) {
      case 'OPEN':
        executeOpen();
        // ERROR: Missing break
    
      case 'CLOSED':
        executeClosed();
        break;
    }
    

    支持空的case,此时允许穿透

    var command = 'CLOSED';
    switch (command) {
      case 'CLOSED': // Empty case falls through.
      case 'NOW_CLOSED':
        // Runs for both CLOSED and NOW_CLOSED.
        executeNowClosed();
        break;
    }
    

    如果真的需要穿透,需要借助continue语句

    var command = 'CLOSED';
    switch (command) {
      case 'CLOSED':
        executeClosed();
        continue nowClosed;
      // Continues executing at the nowClosed label.
    
      nowClosed:
      case 'NOW_CLOSED':
        // Runs for both CLOSED and NOW_CLOSED.
        executeNowClosed();
        break;
    }
    

    try/throw/rethrow/catch/finally

    1. Dart可以throw任何对象,不仅限于exception
    2. 在判断throw时,on或者catch都可以(也可以同时使用),用on表示只关心抛出的类型,用catch表示关心抛出的具体对象
    3. catch时,堆栈为可选参数,即第一个参数为抛出的对象,第二个为堆栈(StackTrace)堆栈
    4. 通过rethrow,重新抛出该异常
      捕获单个throw
    try {
      breedMoreLlamas();
    } on OutOfLlamasException {
      buyMoreLlamas();
    }
    

    捕获多个throw

    try {
      breedMoreLlamas();
    } on OutOfLlamasException {
      // A specific exception
      buyMoreLlamas();
    } on Exception catch (e) {
      // Anything else that is an exception
      print('Unknown exception: $e');
    } catch (e) {
      // No specified type, handles all
      print('Something really unknown: $e');
    }
    

    带堆栈,并继续抛出异常

    try {
      // ···
    } on Exception catch (e) {
      print('Exception details:\n $e');
    } catch (e, s) {
      print('Exception details:\n $e');
      print('Stack trace:\n $s');
      rethrow;// Allow callers to see the exception.
    }
    

    相关文章

      网友评论

          本文标题:dart语言学习笔记-2

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