写给前端工程师的Dart教程(1):Dart 介绍与基础
Dart 简介
我们为什么要学习 Dart ?
因为要学习 Flutter , Flutter 是以 Dart 作为基础语言的框架。脱离了 Flutter 有别的应用场景吗?目前来说还不多。
但这门语言有有趣,开发体验很不错,结合了 C++,Java,Js 等多门语言的优势,而且 flutter 本身也有意义,所以我们是很有理由去学习它的。
Dart 是 google 开发的,强类型的,面向对象,函数作为第一公民的语言。(与 TS 有点像。)
下面引用一张 whoitao 老师的图:对 JS 和 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
这里的 var
和 const
与 JS 中完全不同。
Dart 中,var
关键字会自动推导该变量的类型,而后续给该变量更改值时,只能赋值为同一类型的。否则报错!
final
与 const
都是声明不可修改的常量。
他们的区别在哪呢?
final 与 const 都声明一个无法修改的常量,但 const 关键字声明的变量,必须在编译时就有明确的值(也就是说他必须是一个字面量),而 final 可以赋值一个需要运算才能得到的值(比如一个函数的返回值)
说根本一点,不能将运行时的值分配给 const, const 必须赋值为在 编译时 就确定的值
const date1 = DateTime.now(); //报错
final date2 = DateTime.now(); //允许
一些细节
- dart 中的默认值是
null
!(js中是 undefined) - 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"]}";
// 此处 {} 不能省略
}
- dart 中每条语句后必须有 分号!
- dart 中声明 声明字符串可以使用 单引号,双引号,三引号。其中三引号可以声明包含换行符的字符串。
- 使用布尔值时要注意,在 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
,这表明 set
的 add
方法返回的是 该元素是否被成功加入 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 中的函数。
转载自:https://juejin.cn/post/7251033389998276668