Flutter:Dart基础语法入门

工作上的需要,被迫上线学习Flutter,看了下文档和线上的专栏,人老了,怕容易忘记,记录下笔记,如果有错误的地方,烦请纠正。

一、Dart简介

Dart是Google在2011年10月正式发布的编程语言,起初的定位是运行在浏览器的脚本语言。是Google大神由于不满JavaScript开发的程序后期难维护问题,而新研发的一种面向对象编程语言。然而nodejs的出现,JavaScript很快覆盖了全栈,很多手机应用和桌面应用也成为了JavaScript的宿主容器。这使Dart始终不温不火,这么多年来内置Dart VM的浏览器厂家也只有Google自己的产品Chrome(现在好像已经移除)。

很多人都有疑问,为什么JavaScript那么火,而Dart的开发者那么稀缺,Flutter会选择Dart作为基础语言去研发呢?这不会提高开发者的介入成本,不利于推广吗?个人感觉应该以下几个原因:

  • Dart是Google自主研发产品,可以避免很多类似Oracle和Android的争议问题。
  • 自主研发语言,可以灵活迭代,为Flutter架构的形成做最有力的支撑。
  • Dart 寻求转型,想弯道超车进入移动开发的领域

那么Google选择了用Dart语言开发Flutter框架,除了我们分析的客观原因外,Dart本身有哪些特性是值得Flutter去选择的?

二、Dart特性

  • Dart是声明式布局语言,易于阅读和可视化,可以不通过可视化构建器,通过热重载直接真机调试。
  • 同时支持JIT(即时编译,JavaScript,Python)和AOT(运行前编译,C,C++)
    Dart在开发阶段,使用了JIT编译,这可以提高它的研发效率,降低研发周期。Flutter最受欢迎的热重载,正是因为这一特性。而发布的时候使用AOT,就不用像RN那样,在JavaScript和原生中建立低效的方法调用映射,因此,Dart具有运行速度快,执行性能好的特点。
  • Drat是单线程模型,不需要像多线程那样处理资源共享和数据同步问题,这也就意味着一个函数执行,就将执行到函数结束为止,期间不会被其他Dart代码所打断。Dart的Isolate(隔离区)不会共享内存,几个单独的worker之间,通过事件循环在事件队列中进行通信(类似Node)。

三、Dart基础语法

Dart的运行依赖于Dart VM,大家可以通过安装Dart SDK,来体验Dart。安装过程以MacOS为例子,可以通过brew安装

brew tap dart-lang/dart
brew install dart

接着在VSCode安装Dart插件和code runner插件即可在vscode中体验Dart编程。

跟很多编程语言一样,Dart同样以main函数作为执行入口

void main() {
  print('hello world');
}

Dart变量

Dart可以通过var关键字创建变量,当使用var时,类型是通过编译器推断决定.

var name = 'tony';
print(name is String); // true

在默认情况下,未初始化的变量值为null,所以我们不需要担心无法判断一个传递过来的变量是undefined还是null(JavaScript的表示泪目),所以不需要各种if else。

var name;
print(name); // null

Dart类型

Dart是类型安全的语言,一切皆为对象的设计思路,任何类型都是对象类型,都继承了顶层的Object。类如bool,int,null,函数,都是继承于Object。

String name;
print(name is Object); // true
bool isPig;
print(isPig is Object); // true
int num;
print(num is Object); //true
void fun() {}
print(fun is Object); //true
  • 布尔类型

    在Dart中,使用bool关键字来定义布尔类型,而布尔类型只有两个值,true和false,它们都是编译时常量。

    var c1 = true;
    var c2 = false;
    print(c1 is bool); // true
    print(c2 is bool); // true
    
  • 数值类型

    在Dart中,使用num关键字来定义数值类型,num有两个子类,分别为int代表整数类型和double代表浮点类型

    num n = 10;
    print(n is int); // true
    num m = 1.1;
    print(m is double); // true
    

    除了常见的基本运算符,比如 +、-、*、/,以及位运算符外,你还能使用继承自 num 的 abs()、round() 等方法,来实现求绝对值、取整的功能。你会发现,这些常见的运算符都继承于num

  • 字符串类型

    在Dart中,String 由 UTF-16 的字符串组成。你可以使用${}内嵌表达式在字符串中,如果是一个表示符,可以省略{}

    var name = 'chong';
    print('my name is $name'); // my name is chong
    print('toUpperCase: ${name.toUpperCase()}'); //toUpperCase: CHONG
    

    字符串的拼接,与JavaScript一样,Dart用“+”运算符来拼接。

    var x1 = 'chong';
    var x2 = '...';
    print(x1 + x2); // chong...
    

    对与多行字符串的拼接,Dart提供了类似JavaScript的模版字符串功能。用三个单引号或者三个双引号声明

    var str = '''
        my
        name
        is
        chong
      ''';
      print(str); 
      /*
        my
        name
        is
        chong
      */
    
  • 集合类型

    在Dart中,集合类型包含了数组类型和字典类型,分别对应List和Map,声明和使用,都跟Javascript差不多

      var name = ['zhangsan', 'lisi'];
      name.add('wangwu');
      name.forEach((f) => print('$f')); // zhangsan lisi wangwu
    
      var map = {"name": 'chong', "sex": 'boy'};
      map['n'] = 'hello';
      map.forEach((k, v) => print('$k: $v')); // name: chong sex: boy n: hello
    

    在定义name时,编译器会推断该List为List,所以如果add的是个int或者其他类型,会类型错误。同理 map 会被推断成Map<String, String>,当然,也可以从定义的时候设定类型,而避免推断错误。

      var map = <String, String>{"name": 'chong', "sex": 'boy'};
      map['n'] = 'hello';
      map.forEach((k, v) => print('$k: $v')); // name: chong sex: boy n: hello
    

Dart常量

Dart中定义常量的关键字有两个,const和final,const的使用方法跟JavaScript的一样。const和final的区别主要是const是在编译时期已经确定的值,而final可以定义运行时的值,一旦运行结束,即不可改变。

```
  var x = 10;
  var y = 2;
  final z = x / y; 
  print(z); // 5.0
  const h = x / y; 
  print(h); // Error
```

Dart运算符

Dart的大多数运算符与其他编程语言的类似。有几个比较特殊的运算符,用来简化处理null的情况

  • ??运算符,x??y,表示x为空时,取y的值,x非空时,取x的值

      var x;
      var y = 10;
      var z = x ?? y;
      print(z); // 10
    
  • ?.运算符,x?.y 如果x为null,跳过该语句,避免报错

      var x;
      print(x?.y); // null
    
  • ??=运算符, x??=y,如果x为null,把y赋值给x。如果x不为null,跳过。

      var x = 10;
      var y = 20;
      x ??= y;
      print(x); // 10
    
      var x;
      var y = 20;
      x ??= y;
      print(x); // 20
    

在Dart中,一切皆对象,所以运算符也是对象成员函数中的一部分。当你在某些应用场景需要复写运算符时,Dart也提供了复写机制,只要通过 operator 关键字复写即可.

class Demo {
  var x, y;
  Demo(this.x, this.y);
  Demo operator +(Demo z) => Demo(x + z.x, y + z.y);
  bool operator ==(Demo v) => v.x == x && v.y == y;
}

var x = Demo(3, 3);
var y = Demo(2, 2);
var z = Demo(1, 1);
print(x == (y + z)); // true

四、函数

Dart的函数由返回值、函数名、参数、函数体4部分组成,函数也是对象,它的类型为Function,这也意味着函数可以被定义为变量和作为函数参数。

  bool isCheck(int x, int y) {
    return x == y;
  }

  void printBool(Function check) {
    print('${check(1, 1)}');
  }

  printBool(isCheck); // true

Dart函数也支持箭头表达式,使用方法跟Javascript一致。如上面的例子可以简化为

  bool isCheck(int x, int y) => x == y;

  void printBool(Function check) => print('${check(1, 1)}');

  printBool(isCheck); // true

作为集大多数语言优点为一身的编程语言,Dart设计非常灵活的函数传参设计。设计了通过{}指定传参,设置了通过[]设置可选参数。这也使Dart的代码更加简洁优雅。不会像JavaScript一样,如果函数需要三个参数,前两个为空时,必须占位。下面通过一个例子来记录一下Dart函数的传参。

  void demo1({int x, int y}) => print('$x,$y');
  demo1(y: 2); // null,2

  void demo2(int x, [int y]) => print('$x,$y');
  demo2(1); // 1,null
  demo2(1, 2); // 1,2

  void demo3(int x, int y) => print('$x,$y');
  demo3(1, 2); // 1,2
  demo3(1); // Error

  void demo4(int x, {int y}) => print('$x,$y');
  demo4(1); // 1,null
  demo4(1, y: 2); // 1,2
  demo4(y: 2); // Error

五、类

对象是类的实例,在Dart里,所有对象都继承了顶层的Object,Dart中的类定义,实例话,方法引用,跟JavaScript ES6差不多。差别点是Dart中通过 “_” 来表示私有,声明变量和方法时,在前面加上下划线,表示为private,没加的,表示为public。

class Cat {
  var color, tail; // 颜色、尾巴
  Cat(this.color, this.tail);

  printInfo() {
    print('这是一只${color}毛发, ${tail}尾巴的猫🐱');
  }
}

var cat = new Cat('蓝色', '长');
cat.printInfo(); // 这是一只蓝色毛发, 长尾巴的猫🐱
  • 构造函数

    Dart中,类的构造函数有同名构造函数和命名构造函数两种,同名构造函数,如上面代码所示,与类同名。而命名构造函数,用以下方式定义

    class Cat {
      var color, tail; // 颜色、尾巴
      Cat(this.color, this.tail);
      Cat.defaut(var color) : this(color, '短'); // 重定向构造函数,用":"符号调用
    
      printInfo() {
        print('这是一只${color}毛发, ${tail}尾巴的猫🐱');
      }
    }
    
    var cat2 = Cat.defaut('白色');
    cat2.printInfo(); // 这是一只白色毛发, 短尾巴的猫🐱
    
  • 复用

    在面向对象编程语言中,复用是个很重要的概念,很多编程语言都有继承承,接口等概念,来实现代码的复用。Dart也不例外,Dart中,也引入了继承,接口的概念。

    class Animal {
      var color, tail;
      Animal(this.color, this.tail);
    
      printInfo() {
        print('这是一只${color}毛发, ${tail}尾巴的猫🐱');
      }
    }
    
    class Cat extends Animal {
      var type = '大型';
      Cat(color, tail, {type}) : super(color, tail);
      @override
      printInfo() {
        print('这是一只${color}毛发, ${tail}尾巴的猫🐱,属于${type}猫科');
      }
    }
    
    class Dog implements Animal {
      @override
      var color, tail;
      @override
      printInfo() {
        print('这是一只小狗');
      }
    }
    
    var cat = new Cat("黑色", "长")..printInfo(); // 这是一只黑色毛发, 长尾巴的猫🐱,属于大型猫科
    var dog = new Dog()..printInfo(); // 这是一只小狗
    

    除了继承和接口实现复用外,Dart还提供了Mixins方式。Mixins的中文意思是混入,就是在类中混入其他功能。在Dart中可以使用mixins实现类似多继承的功能。

    class Poultry {
      printInfo() {
        print('这是一种家畜');
      }
    }
    
    class Big with Poultry {}
    
    var big = new Big().printInfo(); // 这是一种家畜
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值