美文网首页
Dart 语法学习笔记一

Dart 语法学习笔记一

作者: _烩面_ | 来源:发表于2021-06-21 10:10 被阅读0次

    Dart 是谷歌于2011年10月10日发布一门开源编程语言(日子挑的不错)。2018年之前一直处于蛰伏状态,flutter 之后声名雀起,一发不可收拾!

    Dart 的存在的存在的意义是什么呢?看一下官网的概述:

    Dart is a client-optimized language for developing fast apps on any platform. Its goal is to offer the most productive programming language for multi-platform development, paired with a flexible execution runtime platform for app frameworks.

    废话说完了,进入正题!

    Hello Dart

    怎么能少得了 Hello World !

    // 程序入口函数
    void main() {
      // 函数调用
      printHelloWorld();
    }
    
    // 定义函数 printHelloWorld
    void printHelloWorld() {
     // 实现,打印 Hello World
      print("Hello World !");
    }
    

    如上,一个简单的 Hello World 就写完了。可以自己打开 DartPad 进行练手!
    Dart 语法学习的过程中均可在其上进行练习,灰常方便!

    Dart 语言特点

    Dart 语言具有以下特点:
    0、编译型;
    1、强类型(Dart 2 才是);
    2、面向对象,一切皆对象,数字、函数、null 都是对象;

    语法

    变量
    使用关键字 var 进行变量的声明。

    // 声明一个字符串变量 name 并赋值 Yuri
    var  name = "Yuri";
    // 声明一个变量 temperature 并赋值 35.0
    var temperature = 35.0;
    

    由于 Dart 有类型推断机制,name 会被自动判断为 String 类型。
    也可以使用类型显式的声明一个变量:

    String name = "Yuri";
    double temperature = 28.5;
    

    还可以使用 dynamicObject 声明一个变量。dynamicObject 的变量可以在后期改变赋值的类型,而 Var 声明的变量则不可以。 dynamic 这个特性与 Objective-C 中的 id 作用很像. dynamic 的这个特点使得我们在使用它时格外需要注意,因为很容易引入运行时错误。

    dynamic name = "Yuri";
    Object temperature = 28.5;
    print("$name, $temperature");
    // 打印结果:Yuri, 28.5
    
    name = 28.5;
    temperature = "Yuri";
    print("$name, $temperature");
    // 打印结果:28.5, Yuri
    

    常量
    使用关键字 finalconst 声明一个常量。

    // 使用 final 声明一个 sex 的常量
    final sex = "male";
    // 使用 const 声明一个 nickName 的常量
    const nickName = "Kitty";
    

    使用 finalConst 声明的常量的值不能被修改。

    finalconst 的区别在哪呢?
    const 定义的常量在编译时就已经固定,final 定义的常量则在第一次使用时才被初始化。

    Dart 内建类型

    Number
    Number 有两种类型 intdouble

    // 定义一个 int 类型变量
    int x = 1;
    // 定义一个 double 类型变量
    double y = 3.14;
    

    int 整数值不大于64位, 具体取决于平台。 在 Dart VM 上, 值的范围从 -263 到 263 - 1. Dart 被编译为 JavaScript 时,使用 JavaScript numbers, 值的范围从 -253 到 253 - 1.
    double: 64位(双精度)浮点数,依据 IEEE 754 标准。

    String
    Dart 字符串是一组 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} 的方式内嵌表达式。 如果表达式是一个标识符,则{} 可以省略。

    var s = 'string interpolation';
    print("Dart has $s, which is very handy.");
    

    在 Dart 中通过调用就对象的 toString() 方法来得到对象相应的字符串。

    String oneAsString = 1.toString();
    assert(oneAsString == '1');
    
    String piAsString = 3.14159.toStringAsFixed(2);
    assert(piAsString == '3.14');
    

    可以使用 + 运算符来把多个字符串连接为一个,也可以把多个字面量字符串写在一起来实现字符串连接。

    var s1 = 'String '
        'concatenation'
        " works even over line breaks.";
    print(s1);
    // 打印结果: String concatenation works even over line breaks.
    
    var s2 = 'The + operator ' + 'works, as well.';
    print(s2);
    // 打印结果:The + operator works, as well.
    

    Boolean
    bool,表示布尔值,有 truefalse 两个值。

    bool isSunny = true;
    bool isRainy = false;
    

    List (也被称为 Array)
    List 表示有序集合。

    // 定义一个 整形 的数组字面量
    var list = [1, 2, 3];
    
    // 获取数组长度
    var length = list.length;
    
    // 访问数组元素. List 元素的下标也是从 0 开始的
    var secondValue = list[1];
    

    Map
    通常来说, Map 是用来关联 keys 和 values 的对象。

    var gifts = {
      // Key:    Value
      'first': 'partridge',
      'second': 'turtledoves',
      'fifth': 'golden rings'
    };
    
    var nobleGases = {
      2: 'helium',
      10: 'neon',
      18: 'argon',
    };
    

    也可以使用 Map 的构造函数创建对象。

    var gifts = Map();
    gifts['first'] = 'partridge';
    gifts['second'] = 'turtledoves';
    gifts['fifth'] = 'golden rings';
    
    var nobleGases = Map();
    nobleGases[2] = 'helium';
    nobleGases[10] = 'neon';
    nobleGases[18] = 'argon';
    

    向 Map 添加一个 key-value

    gifts["sixth"] = "cake";
    

    访问 Map 中的 value

    var sixthGift = gifts["sixth"];
    assert(sixthGift == "cake");
    

    Set
    Set 表示无序元素的集合,集合内元素唯一。

    var halogens = {'fluorine', 'chlorine', 'bromine', 'iodine', 'astatine'};
    

    创建一个空集

    var names = <String>{};
    

    向 set 中添加元素

    names.add("1");
    names.addAll({"2", "3"});
    

    Rune (用于在字符串中表示 Unicode 字符)
    Dart 字符串是一系列 UTF-16 编码单元,即每个字符占 16 位, 而 Unicode 则是 32 位的,因此 Dart 字符串中表示 32 位 Unicode 值需要特殊语法支持。

    Runes input = new Runes(
          '\u2665  \u{1f605}  \u{1f60e}  \u{1f47b}  \u{1f596}  \u{1f44d}');
    print(new String.fromCharCodes(input));
    

    Symbol
    一个 Symbol 对象表示 Dart 程序中声明的运算符或者标识符。 你也许永远都不需要使用 Symbol ,但要按名称引用标识符的 API 时, Symbol 就非常有用了。 因为代码压缩后会改变标识符的名称,但不会改变标识符的符号。 通过字面量 Symbol ,也就是标识符前面添加一个 # 号,来获取标识符的 Symbol 。

    #radix
    #bar
    

    Symbol 字面量是编译时常量。

    函数

    Dart 中一切皆对象。函数也是对象,其对应的类型为 Function

    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; } 的简写。 => 符号 有时也被称为 箭头 语法。

    在 Dart 语言中,函数是一等对象(难道还有二等,三等?)。
    函数可以作为另一个函数的参数,同时也可以把函数赋值给一个变量。

    void printElement(int element) {
      print(element);
    }
    
    var list = [1, 2, 3];
    // 将 printElement 函数作为参数传递。
    list.forEach(printElement);
    
    // 将函数作为值赋给变量
    var loudify = (msg) => '!!! ${msg.toUpperCase()} !!!';
    assert(loudify('hello') == '!!! HELLO !!!');
    

    匿名函数
    一般情况下函数是有名字的,把没有名字的函数叫做匿名函数
    匿名函数有时也被称为 lambda 或者 closure
    在将函数作为值赋值给变量时,我们用的就是一个匿名函数。

    可选参数
    可选参数分命名参数位置参数。一个参数只能选择其中一种进行修饰。

    命名可选参数

    /// Sets the [bold] and [hidden] flags ...
    void enableFlags({bool bold, bool hidden}) {
      ...
    }
    

    调用

    enableFlags(bold: true, hidden: false);
    

    命名可选参数可以用 @required 进行修饰,表示在函数调用时该参数不可缺少。

    const Scrollbar({Key key, @required Widget child})
    

    此时 Scrollbar 是一个构造函数, 当 child 参数缺少时,分析器会提示错误。

    位置可选参数
    将参数放到 [] 中来标记参数是可选的

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

    默认参数
    在定义函数时,我们可以给参数一个默认值。

    /// 设置 [bold] 和 [hidden] 标志 ...
    void enableFlags({bool bold = false, bool hidden = false}) {
      ...
    }
    
    // bold 值为 true; hidden 值为 false.
    enableFlags(bold: true);
    

    运算符

    算术运算符

    操作符 功能
    +
    -
    *
    /
    ~/ 除法取整
    % 模(余数)

    除了上面的基本的算术运算符,Dart 同样也支持带有前缀的自增和自减运算符。
    ++exprexpr++--exprexpr--

    /// 基本操作运算符示例
    assert(2 + 3 == 5);
    assert(2 - 3 == -1);
    assert(2 * 3 == 6);
    assert(5 / 2 == 2.5); // 结果是双浮点型
    assert(5 ~/ 2 == 2); // 结果是整型
    assert(5 % 2 == 1); // 余数
    
    /// 自增自减运算符示例
    var a, b;
    
    a = 0;
    b = ++a; // a自加后赋值给b。
    assert(a == b); // 1 == 1
    
    a = 0;
    b = a++; // a先赋值给b后,a自加。
    assert(a != b); // 1 != 0
    
    a = 0;
    b = --a; // a自减后赋值给b。
    assert(a == b); // -1 == -1
    
    a = 0;
    b = a--; // a先赋值给b后,a自减。
    assert(a != b); // -1 != 0
    

    关系运算符

    操作符 功能
    == 等于
    != 不等于
    > 大于
    >= 大于等于
    < 小于
    <= 小于等于

    比较简单,不再示例。

    类型判定运算符

    操作符 功能
    as 类型转化
    is 类型判断(True if the object has the specified type)
    is! 类型判断(False if the object has the specified type)

    is 比较好理解,是就返回 true,不是就返回 false;
    is! 意义则相反,不是就返回 true,是就返回 false;
    个人感觉大部分情况下,is 就够了!

    赋值运算符

    = 是基本的赋值运算符,通过与其它操作符的组合,会产生许多其它的复合赋值运算符。如下

    = -= /= %= >>= ^=
    += *= ~/= <<= &= |=

    比较简单,不再示例。

    逻辑运算符

    操作符 含义
    &&
    ||
    !

    不再示例。

    按位和移位运算符

    操作符 含义
    & 按位与(AND)
    | 按位或(OR)
    ^ 按位异或(XOR)
    ~expr 取反(Unary bitwise complement (0s become 1s; 1s become 0s))
    << 左移(Shift left)
    >> 右移(Shift right)

    条件表达式

    condition ? expr1 : expr2
    如果条件为 true, 执行 expr1 (并返回它的值): 否则, 执行并返回 expr2 的值。

    var visibility = isPublic ? 'public' : 'private';
    

    expr1 ?? expr2
    如果 expr1 是 non-null, 返回 expr1 的值; 否则, 执行并返回 expr2 的值。

    String playerName(String name) => name ?? 'Guest';
    

    级联运算符

    级联运算符 .. 可以实现对同一个对像进行一系列的操作。除了调用函数, 还可以访问同一对象上的字段属性。

    querySelector('#confirm') // 获取对象。
      ..text = 'Confirm' // 调用成员变量。
      ..classes.add('important')
      ..onClick.listen((e) => window.alert('Confirmed!'));
    

    这个运算符在 iOS 开发过程中没有遇到过,应该是 Dart 特胡的语法糖。

    其它运算符

    Operator Name Meaning
    () Function application Represents a function call
    [] List access Refers to the value at the specified index in the list
    . Member access Refers to a property of an expression; example: foo.bar selects property bar from expression foo
    ?. Conditional member access Like ., but the leftmost operand can be null; example: foo?.bar selects property bar from expression foo unless foo is null (in which case the value of foo?.bar is null)

    控制流程语句

    if ... else ...

    注意:条件语句必须是布尔值

    if (isRaining()) {
      you.bringRainCoat();
    } else if (isSnowing()) {
      you.wearJacket();
    } else {
      car.putTopDown();
    }
    

    for loops

    var message = StringBuffer('Dart is fun');
    for (var i = 0; i < 5; i++) {
      message.write('!');
    }
    

    while and do-while loops

    while (!isDone()) {
      doSomething();
    }
    
    do {
      printLine();
    } while (!atEndOfPage());
    

    break and continue

    break: 停止程序循环。
    continue:跳过当次循环。

    while (true) {
      if (shutDownRequested()) break;
      processIncomingRequests();
    }
    
    for (int i = 0; i < candidates.length; i++) {
      var candidate = candidates[i];
      if (candidate.yearsExperience < 5) {
        continue;
      }
      candidate.interview();
    }
    

    switch and case

    注意:正常情况下,case 中的 break 不可省略。

    var command = 'OPEN';
    switch (command) {
      case 'CLOSED':
        executeClosed();
        break;
      case 'PENDING':
        executePending();
        break;
      case 'APPROVED':
        executeApproved();
        break;
      case 'DENIED':
        executeDenied();
        break;
      case 'OPEN':
        executeOpen();
        break;
      default:
        executeUnknown();
    }
    

    assert

    如果 assert 语句中的布尔条件为 false , 那么正常的程序执行流程会被中断。

    // 确认变量值不为空。
    assert(text != null);
    
    // 确认变量值小于100。
    assert(number < 100);
    
    // 确认 URL 是否是 https 类型。
    assert(urlString.startsWith('https'));
    

    异常处理

    Dart 可以抛出和捕获异常。
    throw
    throw 用于抛出异常。
    当函数执行过程中出现了异常,可以通过 throw 将异常抛出。异常可以是 Exception 或 Error,或其它任何非 null 对象。当抛出异常时,程序也将会被终止。

    throw FormatException('Expected at least 1 section');
    

    以下示例抛出了一条字符串消息

    throw 'Out of llamas!';
    

    catch
    捕获异常可以避免异常继续传递.

    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
    不管是否抛出异常, 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.
    }
    

    Dart 语法学习笔记二

    相关文章

      网友评论

          本文标题:Dart 语法学习笔记一

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