likes
comments
collection
share

写给前端工程师的Dart教程(1):Dart 介绍与基础

作者站长头像
站长
· 阅读数 9

Dart 简介

我们为什么要学习 Dart ?

因为要学习 Flutter , Flutter 是以 Dart 作为基础语言的框架。脱离了 Flutter 有别的应用场景吗?目前来说还不多。

但这门语言有有趣,开发体验很不错,结合了 C++,Java,Js 等多门语言的优势,而且 flutter 本身也有意义,所以我们是很有理由去学习它的。


Dart 是 google 开发的,强类型的,面向对象,函数作为第一公民的语言。(与 TS 有点像。)

下面引用一张 whoitao 老师的图:对 JS 和 Dart 做了生态上的横向对比

写给前端工程师的Dart教程(1):Dart 介绍与基础

Dart 结合了多个语言的长处,开发起来比较舒服,更加偏向面向对象一些,但也有使用函数式编程的能力,因为他的函数作为一等公民。

Flutter 是 Dart 的框架,就好比 React 和 JS 之间的关系,另外,Dart 也有自己的第三方包管理工具, 在 bub.dev 可以查看发布出来的一系列包。

Hello world

根据程序员的传统艺能,我们肯定得先来一个 hello world.

JS 的执行在预编译后,从上往下依次执行。与 JS 不同的是,Dart 必须要有一个 入口 函数 main 函数,这与 C语言相同。 Dart 在运行时,从 main 函数开始运行。

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

打印语句是其他语言中常见的 print函数。

这个函数是哪里来的呢?

Dart 在执行时,会默认导入核心包 dart:core,该包中包含了 print函数,这也是我们能使用它的理由:

如同下面的代码:(dart:core 包是自动导入的,我们不需要手动导入)

import "dart:core"
void main(){
  print("hello world");
}

另外,每一个语句后必须要有分号,否则编译不通过,这与JS有很大的区别。

类型

与JS不同的是,Dart 是一门 强类型语言,这意味着编译器需要知道每个变量是什么类型.

首先,我想强调的是,在Dart中,无论什么类型的数据,本质上都是一个对象。

Dart 中,万物皆对象!

int a = 1;
bool b = true;

是的 , a 和 b 都是对象。Dart 中所有的值都是对象。

void main(){
  int a = 1;
  print(a.toString());
}

看到了吗,我们可以调用 a.toString(),这说明,a是一个对象!!他的类是 Number

下面是一些常见的类型:

  • Number:
    • num (可以是整数也可以是小数)
    • int (整数)
    • double (浮点数)
  • Boolean
    • bool(布尔值)
  • String(字符串)
  • List(一组有序对象, 对标JS中的数组)
  • Set(一组无序对象)
  • Map(键值对映射对象)
  • Object(老油条,是任何对象的基类)
  • dynamic(该类型是告诉编译器,在运行时在判断,有安全风险,类似于 TS 中的 any
  • Function(函数,从这你可以看出,Dart 与 JS 相似,函数是一种特殊的对象,也是其作为一等公民的原理
  • Symbol

需要特别说明的是: Dart 中 变量的默认值是 null而不是 js 中的 undefined

关于一些基础的API 上述中的类型,都有内置的API,比如 Number 类型的实例有 gcd ,round 方法等等,这些可以在官网中查到,而且都是些见名知意的东西,就不单独讲了。

API网站:api.dart.cn

变量声明

Dart 声明变量有两种方式,一种是声明其具体的类型,一种是声明其权限,然后让 dart 推导其类型。用过 TS 或者 Rust 的朋友可能比较熟悉这种方式。

1.明确类型

这种方式就是使用 变量类型作为关键字声明变量,该变量后续只能被修改为同类型的变量,否则报错

void main(List<String> args) {
  int a = 1;
  a = "123"; //报错
}

2.类型推导

var a  = 20;
final b1 = "ABC"
const b2 = "CCC"

可以使用另外三个关键字声明变量:

  • var
  • final
  • const

这里的 varconst 与 JS 中完全不同。

Dart 中,var关键字会自动推导该变量的类型,而后续给该变量更改值时,只能赋值为同一类型的。否则报错!

finalconst都是声明不可修改的常量。

他们的区别在哪呢?

final 与 const 都声明一个无法修改的常量,但 const 关键字声明的变量,必须在编译时就有明确的值(也就是说他必须是一个字面量),而 final 可以赋值一个需要运算才能得到的值(比如一个函数的返回值)

说根本一点,不能将运行时的值分配给 const, const 必须赋值为在 编译时 就确定的值

const date1 = DateTime.now(); //报错
final date2 = DateTime.now(); //允许

一些细节

  1. dart 中的默认值是 null !(js中是 undefined)
  2. dart 中也有模版字符串:
void main(){
  var b  = "world";
  var str = "hello ${b}";
}

其中, $后的花括号在某些情况下是可以省略的:

void main(){
  var b  = "world";
  var str = "hello $b";
}

但是,如果是访问一个成员属性,不能省略大括号

void main(){
  final map = {
    "a" : "world"
  };
  var a = "hello ${map["a"]}";
  // 此处 {} 不能省略
}
  1. dart 中每条语句后必须有 分号!
  2. dart 中声明 声明字符串可以使用 单引号,双引号,三引号。其中三引号可以声明包含换行符的字符串。
  3. 使用布尔值时要注意,在 Dart 中没有 JS中的隐式类型转换。 所以 Dart 中没有 ===

运算符

此处我们只对与 JS 有区别的地方做说明,其他操作与 JS 相同。

地板除 ~/

这个很 ez,就是对除法结果做向下取整

避空运算符 ??

void main(){
 var b = null;
 var a = b ?? 1;
 // a = 1
}

这个东西就类似于下面这段代码:

var a = b == null ? b : 1;

如果 b 是 null 则取后面的值,否则取 b 的值。

级联运算符..

我们有下面代码:

void main() {
  final set = new Set();
  print(set.add(1)); //true
}

打印结果是 true,这表明 setadd方法返回的是 该元素是否被成功加入 set;

再看我们使用级联运算符:

void main() {
  final set = new Set();
  print(set..add(1)); //{1}
}

打印结果是 set对象本身。

对象.方法的形式返回的是该方法的返回值

对象..方法点形式返回的是该对象本身。

他有什么用?当然是连续的操作某一个对象:

void main(){
  final set = new Set();
  set
    ..add(1)
    ..add(2)
    ..add(3);
  print(set); //{1,2,3};
}

结语

Dart 中的函数也有很多与JS不同的地方,我们在下一节来讲一讲 Dart 中的函数。