Dart
Dart是一种面向对象的语言,具有C语言风格的语法,可以选择将它编译成JavaScript。
环境安装
安装flutter的时候就安装了Dart的SDK,这里省略SDK的安装。
在VS Code中安装Dart插件和Code Runner直接就可以运行Dart程序了,用来学习语法。
HelloWorld
mail()函数是Dart中的预定义方法,此方法充当应用程序的入口,Dart脚本需要main()方法来执行。
void main(List<String> args) {
print('hello,dart.');
}面向对象
class Test{
void sout(){
print('Test');
}
}
void main(List<String> args) {
Test test = new Test();
test.sout();
}数据类型
数字
字符串
布尔
列表
集合
映射
符文
符号
数字
Dart中的数字类型用于表示数字文字
整数,用于表示非小数值,使用int关键字表示整数
双精度数,使用double表示浮点
使用.parse()方法将文字转为数字,用.toString()转为字符串
void main(List<String> args) {
int i1 = 1;
var i2 = 1;
var i3 = int.parse('1');
print(i1);
print(i2);
print(i3);
double d1 = 1.1;
var d2 = 1.1;
var d3 = double.parse('1.1');
print(d1);
print(d2);
print(d3);
}int类型支持按位移动(<< , >>)与(&)和或(|)运算
字符串
Dart字符串是一系列UTF-16代码单元,符文用来表示UTF-32代码单元序列,关键字String用于表示字符串,用单引号和双引号都可以用来创建字符串。
可以使用${expression}将表达式的值放在字符串中,如果表达式是表示符,则可以跳过{},为了获得对应于对象的字符串,Dart调用.toString()方法。可以使用+拼接字符串。
void main(List<String> args) {
var s1 = 'hello,world.';
var s2 = "hello,dart.";
var s3 = '$s1' + '${s2.toUpperCase()}';
print(s3);
}可以使用三引号(''' ''' 或 """ """)创建多行字符串,可以通过在左引号前加r来创建原生字符串。
void main(List<String> args) {
var s = r'''
Hello!
World!''';
print(s);
}文字字符串是编译时常量,只要任何插值表达式是一个编译时常量,其值为null、数值、字符串或布尔值都可以。
void main(List<String> args) {
const constNum = 0;
const constBool = true;
const constString = 'hello';
const constList = [1,2,3];
var varNum = 0;
var varBool = true;
var varString = 'hello';
const success = '$constNum $constBool $constString';// constList也不能加进来
// 不可以像下面这么些
// const fail = '$varNum $varBool $varString';
}布尔
关键字bool,Dart的类型安全不能使用if(nonbooleanValue)或assert(nonbooleanValue)之类的代码,必须明确检查值。
void main(List<String> args) {
var s = '';
assert(s.isEmpty);
var i = 0;
assert(i <= 0);
var v;
assert(v == null);
var nan = 0/0;
assert(nan.isNaN);
print('all success');
// 下面这样是不可以的
// if() print(1);
}列表类型
在Dart中,数组是List对象,Dart列表文字看起来像javaScript数组文字,索引从0开始到list.length-1。
要创建一个编译时常量的列表,请在列表前加const。
Dart2.3引入了扩展运算符(...)和空值感知扩展运算符(...?)提供了一种将多个元素插入集合的简洁方法。
Dart2.3还引入了if和collection的集合,使用它在条件(if)和重复(for)构建集合。
void main(List<String> args) {
var list1 = ['1','2','3'];
var list2;
var f = true;
var list3 = ['0',...list1,...?list2,if(f) '4',for(var i in list1) int.parse(i)+4];
print(list3);
}集合
Dart中Set是无序的唯一项的集合,要创建一个空集合,请使用前面带有类型参数的{},或者将{}赋值类型为Set的变量
void main(List<String> args) {
Set<String> nameSet = {"lilin","lilin"};
print(nameSet);
var set = <String>{};
set.addAll(nameSet);
print(set);
}使用.length获取集合中项目数量,要创建一个编译时常量的集合,请在set文字之前加const
Set<String> nameSet = const {"lilin"};映射
其实就是Map,键和值都可以是任何类型的对象,每个键只出现一次,但可以多次使用相同的值。
void main(List<String> args) {
var map1 = {
1:'1',
2:'2',
3:'3'
};
map1[4] = "4";
print(map1);
}使用.length来获取映射中键值对的数量,要创建一个编译时常量的映射,请在map文字之前添加const关键字
符文
在Dart中,符文是字符串中的UTF-32代码点,Unicode为世界上所有书写系统中使用的每个字母,数字和符号定义唯一的数值,由于Dart是UTF-16代码单元的序列,因此在字符串中表示32位Unicode值需要特殊语法。
String类有几个属性可以用来提取符文信息,codeUnitAt和codeUnit属性返回16位代码单元,使用runes属性获取字符串的符文。
void main(List<String> args) {
var str = 'hello';
print(str.codeUnits);
print(str.runes.toList());
Runes input = new Runes('\u2665 \u{1f605} \u{1f60e} \u{1f47b} \u{1f596} \u{1f44d}');
print(new String.fromCharCodes(input));
}符号
Symbol对象表示Dart程序中声明的运算符或标识符,可能永远不需要符号,但他们对于按名称引用标识符的API非常有用,因为缩小会更改标识符名称而不会更改标识符符号。要获取标识符符号,请使用符号文字,#后跟标识符。符号是编译时常量。
#radix
#barDart中的符号(Symbol)是不透明的动态字符串名称,用于反应库中的元数据。简而言之,符号是一种存储人类可读字符串与优化供计算机使用的字符串之间关系的方法。
反射是一种在运行时获取类型元数据的机制,如类中的方法数,它具有的构造函数数或函数中的参数数,甚至可以调用在运行时加载的类型方法。
变量
Dart中的所有变量都存储对值的引用,而不是包含该值。
Dart通过在变量名前加上数据类型前缀来支持类型检查,类型检查确保变量仅包含特定于数据类型的数据。
未初始化的变量的初始值为null,即使是具有数字类型的变量的初始值也是null,因为数字与Dart中的其他变量一样,都是对象。
dynamic关键字
声明没有未指定静态类型的变量则会隐式声明为dynamic,也可以使用dynamic关键字代替var关键字声明变量。
final和const
final和const关键字用于声明常量,在Dart中,不能修改使用final或const关键字声明变量的值。这些关键字可以与变量的数据类型一起使用,也可以与var一起使用。const关键字用于表示编译时常量,使用const关键字声明的变量是隐式final。
条件
和Java一样
循环
和java一样,有for in
枚举
enum enum_name {
enumeration list
}其中,
enum_name指定枚举类型名称;enumeration list是以逗号分隔的标识符列表;
枚举列表中的每个符号代表一个整数值,一个大于它之前的符号。默认情况下,第一个枚举符号的值为0。
函数
return_type function_name(){
//statements
return value;
}return语句是可选的,没有指定函数则返回null
可选的位置参数
void function_name(param1, [optional_param_1, optional_param_2]) { }如果未传递可选参数值,则将其设置为NULL
可选的命名函数
// 声明函数
void function_name(a, {optional_param1, optional_param2}) { }
// 调用函数
function_name(optional_param:value, …);带有默认值的可选参数
function_name(param1,{param2 : default_value}) {
//......
}e.g.
void main(List<String> args) {
test(1);
}
void test(a,{b:123}){
print(a);
print(b);
}lambda函数
[return_type] function_name(parameters) => expression;接口
Dart没有声明接口的语法,类声明本身就是Dart中的接口,实现使用implements关键字,实现类必须重新定义它希望实现的接口中的每个函数。
void main(List<String> args) {
Blue blue = new Blue();
blue.printColor();
}
class Color{
void printColor(){
print("Color");
}
}
class Blue implements Color{
void printColor(){
print("Blue");
}
}一个类也能实现多个接口,中间用逗号分隔
类
class class_name {
<fields>
<getters/setters>
<constructors>
<functions>
}字段(fields) - 字段是类中声明的任何变量,字段表示与对象有关的数据。
setters和getters - 允许程序初始化和检索类字段的值,默认的getter/setter与每个类相关联。但是可以通过显式定义setter/getter来覆盖默认值。
构造函数(constructors) - 负责为类的对象分配内存。
函数(functions) - 函数表示对象可以采取的操作,它们有时也称为方法。
可以通过对象访问类的属性和函数。使用.点表示法(称为句点)来访问类的数据成员。
命名构造函数
Dart提供了命名构造函数,可以使类有多个构造函数
class_name.constructor_name(param_list)getter和setter
语法:定义一个getter
return_type get identifier
{
}
Dart语法:定义一个setter
set identifier
{
}继承
使用extends关键字继承,Dart支持单层和多级继承,不支持多重继承
重写
使用@override
static
静态成员
对象
级联运算(..)
每次调用都引用该对象
void main(List<String> args) {
Color color = new Color()
..printColor()
..printColor();
}
class Color{
void printColor(){
print("Color");
}
}集合
List
dart:core提供了List类,使用add()和remove()方法
Set
dart:core提供了Set类,提供from()方法,可以从list中直接生成。
void main(List<String> args) {
Set<int> s = new Set.from([1,1,2,2,3,3]);
print(s);
}
// {1, 2, 3}Map
与Java赋值方式不一样
void main(List<String> args) {
Map<int, String> map = new Map();
map[1] = "1";
map[2] = "2";
var three = 3;
map[three] = three.toString();
print(map);
}dart:collection
dart:collection 库提供Dart集合的各种实现类
HashMap
HashSet
LinkedList
Queue
HashMap
提供remove()和clear()方法,remove()传递一个键,clear()清空HashMap
HashSet
也提供remove()和clear()方法
包
Dart的包管理器是pub,包元数据在pubsec.yaml中定义
异常
Dart使用try/on/catch块来处理异常,需要指定异常类型时用on块,当处理程序需要异常对象时用catch块。
try块必须紧跟一个on/catch块或一个finally块(或两者之一)。当try块中发生异常时,控制将转移到catch。
on块和catch块是相互包含的,即try块可以与on块和catch块相关联。
int x = 12;
int y = 0;
int res;
try {
res = x ~/ y;
}
on IntegerDivisionByZeroException {
print('Cannot divide by zero');
} on...catch
int x = 12;
int y = 0;
int res;
try {
res = x ~/ y;
}
on IntegerDivisionByZeroException catch(e) {
print(e);
}finally
和java一样
throw
和java一样
自定义异常
implements Exception
typedef
typedef或函数类型别名有助于定义指向内存中可执行代码的指针,typedef可以用作引用函数的指针。
定义typedef
typedef可以用于指定希望特定函数匹配的函数签名,函数签名由函数的参数(包括类型)定义,返回类型不是函数前面的一部分。
typedef function_name(parameters)将函数分配给typedef变量
typedef的变量可以指向与typedef具有相同签名的函数
type_def var_name = function_name调用函数
typedef可以用于调用函数
var_name(parameters)e.g.
typedef op(int a, int b);
int A(int a,int b){
print(a+b);
return a+b;
}
void B(int a, int b){
print(a);
print(b);
}
void main(List<String> args) {
op o = A;
o(1,2);
o = B;
o(3,4);
}typedef 也可以作为参数传递给函数
typedef op(int a, int b);
int A(int a,int b){
return a+b;
}
void plus(op o){
int i = o(1,2);
print(i);
}
void main(List<String> args) {
op o = A;
plus(A);
}库
使用import关键字导入库,内置Dart库URI使用dart:scheme来引用库。其他库可以使用文件系统路径或package:scheme来指定其URI。包管理器(如pub工具)提供的库使用package:scheme。
Dart脚本可以使用下划线(_)为表示符添加前缀,将其组件标记为私有,Dart库可以通过外部脚本限制对其内容的访问,称为封装
自定义库
声明库
library ltest;
int add(int a, int b){
return a+b;
}使用库
import './test.dart' as l;
void main(List<String> args) {
var i = l.add(1, 2);
print(i);
}异步
暂时用不到,先不学了
并发
暂时用不到