Dart语言学习笔记

安装

如果是windows系统,点击安装SDK:http://www.gekorm.com/dart-windows/
如果是Mac系统,点击安装SDK:https://dart.dev/get-dart
可将dart安装后的bin目录加入到path路径中,打开命令行工具,使用命令dart --version确保dart已安装到您电脑中即可。

为什么要学些这门语言

目前Google推出的最新跨端解决方案Flutter,需要采用Dart语言编写前端代码。Flutter是目前市面上最好的跨端应用解决方案,另外,Dart语言学习门槛低性能好,支持动静态编译,并支持很多高级语言特性。

语法要点

dart语言借鉴了java,js,swift等高级的语言特性,并融入很多使用的语法糖,我们来简要做个概括。

  • 在Dart中所有变量引用的都是对象,继承Object,包括数字,函数,null等都是对象;
  • 在Dart运行之前会解析您的代码,通过使用类型和编译型常量来帮助Dart捕获异常,让代码运行的更高效;
  • Dart支持在方法中定义方法,函数是Dart非常重要的概念;
  • Dart没有public,private,protected关键字,如果要申明私有成员变量或函数请使用_打头;
  • 可以在代码中加入assert断言语句以便让有些错误在编译器就能被捕获;

启动入口

Dart语言也是把main函数作为入口程序。可以给main函数传入List入参来接收命令行参数列表。

内置类型

dart语言使用var声明变量,和swiftid类似,在编译阶段会自动确认其类型。
dart语言只有以下几种内置类型:StringNumberboolMap,List,FunctionSymbolsrunes等,其中Number分为intdouble,注意没有float之类的浮点数类型,可以对Number类型四则运算,其中取整运算符是~/,有一些常用的属性,如isNaN,isEven(是否偶数),isOdd(是否奇数)等,可以做一些简单的类型转换,如int.parse("1");double.parse("1.1"等,注意在Dart中没有数组类型,而统一使用List;

  • 字符串:使用"""多行字符串声明,可以使用$xx${xx}在字符串中使用变量占位符,相邻的字符串拼接的+可省略,但拼接的内容不能是1个空格。
  • 静态变量:可以使用关键字static修饰类访问的变量。
  • Dart字符串是UTF-16 code units字符序列,所以支持emoji表情符,如笑脸: \u{1f600};

类的使用

Dart和Java等高级语言一样,可以定义类,并使用extends继承类,使用@override注解声明你要重写的函数,使用super调用重写这个父类的函数。

Dart语言学习笔记_第1张图片
image

如果要在代码尝试使用类中不存在的方法或实例变量检测时做出反应,可以重写noSuchMethod

可以使用abstract修饰符定义无法实例化的类;

一个类可以使用implements实现多个接口;

可以使用enum定义枚举;

一个类可以通过..使用级联调用语法,比如querySelector("#id")..text="xxx"..onClick.listen(xxx);

泛型

泛型有以下好处:

  • 减少代码重复:泛型允许您在多种类型之间共享单个接口和实现,同时仍然利用静态分析;
  • 代码更友好,编译期提醒:比如列表中的元素指定泛型类型可确保不符合类型的元素被添加;
  • 与Java不同,Dart会在运行期携带类型信息,如List类型的列表,可以使用lists.runtimeType(),获取到类型信息List
  • 可以配合extends来限定参数类型;
  • 泛型可以被使用在包括函数,函数表达式,类方法,类型参数,返回类型等中;

重写操作符

我们可以通过关键字operator关键字重写包括:+,-,*,/,<,>,<=,>=,%,/,[],[]=,,=,<<,>>等十几种运算符:

image

类型自动推断

在声明一个变量时,无需指定类型,系统会自动推断,比如var m= {"a":1};var i=1;,系统自动认为mMap类型i整型。如果一个变量被赋值后,在后续会被另外类型的变量值覆写,应该使用dynamic声明这个变量。

final和const

用来定义常量,都必须初始化,const是编译时常量,只能用编译时常量来初始化,但final可以用变量来初始化,比如final time = new DateTime.now();是允许的。

函数

函数类型是Function,函数可以赋值,也可以作为参数传递给其他函数,这是函数式编程典型特征。在Dart中不能重载函数,函数可以不指定返回类型(实际会返回Object),而实际上函数体可以返回任意类型,如果在函数体中没有return,则返回null。

在我们编写Flutter程序时,经常会碰到函数体只是返回一个布局,那么函数体在一条语句的情况下,可以简写成:void printxx(num n) => print(n);,注意箭头的用法。

另外函数的参数非常有意思,可指定可选参数(使用{}将可选参数括起来),可以通过:或=指定参数默认值,也可以使用位置参数(用[]括起来),注意位置参数如果有多个,必须跟实际传入的是实参一一对应。

函数可以用来赋值,比如:var uu = (msg) => "'${msg.toUpperCase()}'";,以上uu是一个函数,将传入的字符串转换成大写,可以直接调用uu("hello")即返回HELLO

函数也可以作为参数,比如Future.delayed(new Duration(seconds: 2),(){return "hi";}),第二个参数就是一个函数,函数作为参数的用法在Flutter编程中随处可见,是一个非常重要的用法。

构造函数

Dart是不支持函数重载的,那多个构造函数怎么办?我们可以使用命名构造函数,比如Text.a(this.a);Test.ab(this.a,this.b)等命令构造函数

闭包

一个闭包是一个方法对象,不管该对象在何处被调用, 该对象都可以访问其作用域内的变量。方法可以封闭定义到其作用域内的变量。比如以下代码:

Function makeAdder(num addBy) {
  return (num i) => addBy + i;
}
main() {
  var add2 = makeAdder(2);
  var add4 = makeAdder(4);
  assert(add2(3) == 5);
  assert(add4(3) == 7);
}

异步支持

Dart类库有非常多的返回Future或者Stream对象的函数。 这些函数被称为异步函数。async和await关键词支持了异步编程,允许您写出和同步代码很像的异步代码。

Dart语言学习笔记_第2张图片
image

以上写法在Flutter编程中经常被用到,将异步的调用方式以同步的写法呈现,使得我们理解起来更加直观。

元数据注解

元数据注解以字符开头@,后跟对编译时常量(如deprecated)的引用或对常量构造函数的调用。元数据可以出现在typedef类型参数构造函数工厂函数字段参数或变量声明之前以及导入或导出指令之前。您可以使用反射在运行时检索元数据,所有Dart代码都有两个注解:@deprecated@override。你可以定义自己的元数据注解,如下:

Dart语言学习笔记_第3张图片
image

之后就可以使用注解: @todo('name','ddd')

Mixin

有时候将某些行为定义为Mixin,以便让其他类通过with来实现多重继承,减少代码冗余。比如var CC=T with A,B,表示CC类中的方法是T,A,B三个类的方法的并集,当有函数名重名的时候,B的方法覆盖A,T的,A方法覆盖T的。这样就变相支持了多重继承。

反射

dart:mirrors 库提供了基本的反射支持。可以通过#打头定义Symbols,这样在代码混交的情况下也可以保持标识符名称。比如你知道类名,可以直接用new Symbol("CLASSNAME")来构建symbol。比如我们动态调用C类的d方法,d方法有一个参数:

class C{
var tt = "test";
C(){};
static d(msg){print(msg);}
a(){print("C.a";)}
}
//调用类的静态函数
ClassMirror cc = reflectClass(C);
cc.invoke(Symbol("d"), ["hello"]);
//如果调用实例函数
InstanceMirror mm = cc.newInstance(Symbol.empty, []);
mm.invoke(Symbol("a"), []);
//获取类的成员变量
print(mm.reflectee.tt);

此外,还可以通过反射获取注解,元数据等,具体可参考:https://www.jianshu.com/p/d68278d19f79
Flutter中禁止使用反射。

你可能感兴趣的:(Dart语言学习笔记)