一、Dart语言特点
1、Dart所有内容都是对象, 数字number、函数function、null都是对象;同java一样,所有的对象都继承自Object类。
2、Dart是动态类型语言, 尽量给变量定义一个类型,会更安全;同scala,不指定变量类型,编译时系统自动识别数据类型。
3、Dart语言的程序入口为main函数,同c语言一样,main函数是程序的入口点
4、Dart语言的类和接口是统一的,类即接口,可以继承一个类,也可以实现一个类(接口),包含了良好的面向对象和并发编程的支持。
5、Dart 访问权限,默认为公有,以"_"开头意味着对它的 lib 是私有的。
6、Dart常量与最终量,final的值只能被设定一次、const 是一个编译时的常量,可以通过 const 来创建常量值,实例变量可以是 final,但不能是 const。
7、编程语言并不是孤立存在的,Dart也是这样,他由语言规范、虚拟机、类库和工具等组成:
- SDK:SDK 包含 Dart VM、dart2js、Pub、库和工具。
- Dartium:内嵌 Dart VM 的 Chromium ,可以在浏览器中直接执行 dart 代码。
- Dart2js:将 Dart 代码编译为 JavaScript 的工具。
- Dart Editor:基于 Eclipse 的全功能 IDE,并包含以上所有工具。支持代码补全、代码导航、快速修正、重构、调试等功能。
二、Dart基础语法
1、变量
- Dart所有类型都是对象,因此默认值都为null
- Dart可不指定变量类型,编译时根据变量值判断变量具体类型
- final与const声明的变量均不能修改,且在声明时必须初始化,类级别常量要用static修饰
- Dart数据类型有 numbers(int、double)、strings、booleans、lists、maps、symbols
- Dart字符串是UTF-16编码单元的序列。可用“${表达式}”在字符串中运算;可用“$变量”在字符串中获取变量值;可用相邻字符串进行拼接,也可用“+”进行拼接;可以使用三个单引号或三个双引号声明多行字符串。
- Dart条件判断不能像js一样,检查模式下只有true为真,生产模式可用0和1。
- 由于Dart一切皆对象,List以及Map可指定任意类型的key或value
测试代码如下
class Basic{
//类级别常量必须用static修饰
static const TYPE="Basic.class";
//动态数据类型
dynamicType(){
var a=123.1;
Object b="hello world";
dynamic c=123;
print(a.runtimeType); //double
print(b.runtimeType); //string
print(c.runtimeType); //int
}
//变量默认值
defaultValue(){
var d;
print(d);
/*
判断dart变量是否为空语法
variable ?? true; 表示判断变量是否为空
variable ?? false; 表示判断变量是否不为空
*/
print(d ?? true);
}
//最终量与常量
finalAndConst(){
//声明时初始化
final String e="hello world";
const int A=170;
const int B=120;
}
//变量类型测试
variableType(){
//动态变量类型
var a=1;
var b=1.1;
var c=true;
print(a.runtimeType);
print(b.runtimeType);
print(c.runtimeType);
//相邻字符串自动拼接
var d="hello"' ';
print(d.runtimeType);
print("$d${testString()}"+"!");
//多行字符串
String e='''
A:hello!I am Tokily.
B:hi!nice to meet you!
''';
print(e);
//使用r修饰表示单行字符创
String f=r"hello \nworld";
print(f);
//字符串与数字相互转化
Object g="111";
var h=int.parse(g);
print(h.runtimeType);
var i=h.toString();
print(i.runtimeType);
var j=3.1415926;
Object k=j.toStringAsFixed(2);
print(k.runtimeType);
var l=double.parse(k);
print(l.runtimeType.toString()+" $l");
//没有指定数据类型的List可存放多种数据类型元素
var m=[1,2,3,"4"];
for(var i in m){
print(i);
}
print(m.runtimeType);
//map
var n={
1:1,
2:"2",
"3":3
};
n[4]="4";
n.remove(2);
for(var i in n.values){
print(i);
}
}
String testString(){
return "world";
}
}
void main(){
Basic basic=new Basic();
basic.variableType();
}
2、函数
- Dart函数语法结构与Java函数类似,Dart函数默认返回值为void。
- Dart对于仅有一个表达式的函数可以使用function()=>expression,“=> 表达式”语法是“{ return 表达式 }”的简写。
- 可选参数必须在必选参数之后;命名可选参数按名称给参数赋值,位置可选参数按位置赋值;命名可选参数为map对象,位置可选参数为list对象。
- main函数为Dart程序入口,返回值为空,有一个可选参数list。
- Dart作用域按照代码块区分,子代码块,可访问父代码块属性。
以下是测试代码
class Basic{
//未声明返回值类型的函数,默认返回值为void
testDefaultReturn(){
print("没有返回值");
}
//仅有一句表达式的函数可用如下方式编码
bool testSimpleFunction(num a,num b)=>
a>b?true:false;
//可选命名参数
testParameterName(String parameter1,{String parameter2:"world"}){
print("$parameter1 $parameter2");
}
//可选位置参数
testParameterAddress(String parameter1,[String parameter2="hello",String parameter3="world"]){
print("{parameter1:$parameter1,parameter2:$parameter2,parameter3:$parameter3}");
}
printListValue(element)=>
print(element);
//将函数作为object类型参数
traverse(List<Object> list){
list.forEach(printListValue);
}
//语法的封闭性,这里的dividend将一直存在与返回函数中
remainder(int dividend)=>
(int divisor)=>divisor%dividend;
}
void main(){
Basic basic=new Basic();
print(basic.testSimpleFunction(1, 2));
basic.testParameterName("hello");
basic.testParameterName("hello",parameter2:"tokily");
basic.testParameterAddress("hi");
basic.testParameterAddress("one","three","tow");
var a=[1,3.14,true,"hello world"];
basic.traverse(a);
var b=basic.remainder(10);
print(b(21));
// return null; 返回值为void的函数末尾会自动添加这句代码,同c;
}
3、运算符
- Dart运算符与其他高级程序设计语言基本一样,不做深入探讨。
- 需要注意的是,在dart中判断对象是否为空须使用“??”运算符
测试代码如下
//不常见运算符测试
import 'Function.dart' as prefix0;
class Basic{
//两数相除取整数
divisionInteger(int a,int b){
print(a~/b);
}
//自增自减优先级
priority(int f){
int e;
//先赋值,后自增
e=f++;
print("e:$e f:$f");
//先自增,后赋值
e=++f;
print("e:$e f:$f");
//先赋值,后自减
e=f--;
print("e:$e f:$f");
//先自减,后赋值
e=--f;
print("e:$e f:$f");
}
//对象类型运算
objectTypeOperation(a){
print(a is int);
print(a is! int);
//类型装换,向上转化
a as num;
print(a.runtimeType);
}
}
main(){
Basic basic=new Basic();
basic.divisionInteger(5,2);
basic.priority(2);
basic.objectTypeOperation(3.14);
}
4、条件控制
- Dart不同于js,所有不为true的值都为false。
- Dart条件控制语句与java基本相同。 - swith语句被检测数据必须与检测数据类型相同,无论继承关系,case语句块包含其他内容时且该语句块之后还有其他语句块时,缺少break会抛出异常。
- 在case语句块中可使用“continue anchor;”跳转到指定锚点位置 ,类似于c里面的goto
测试代码如下
main(){
String a="hello";
switch(a){
case "hello":
print("hi");
continue anchor;
case "hi":
print("hello");
break;
anchor:
case "ok":
print("thank");
}
}
5、异常
- Dart中所有异常都是不需检测的异常,方法不会声明它会抛出什么异常,也不需要去捕捉任何异常。
- Dart 除了提供 异常、错误 类型以外还提供了众多预定义的子类型。
- Dart程序可以将任何非空对象作为异常抛出,不只局限与异常和错误对象。
- Dart异常的抛出与捕获与Java类似,不同的是Dart通过使用“on Object”捕获指定类型的异常,使用“cache(e)”来获取异常对象。
实例代码如下
//抛出异常方法,dart所有对象均可作为异常抛出
throwException(Object object){
throw object;
}
main(){
try {
throwException(new Exception("测试异常"));
}on num{
print("抛出的是一个数字类型的异常");
}on String{
print("抛出的是一个字符串类型的异常");
}catch(e){
print("获取异常对象 $e");
}finally{
print("此处为必运行处,可做清理回收等操作");
}
}
6、面向对象
- Dart中一切皆对象,所有的类都继承Object类。
- 在 Dart 中所有的类都隐含的定义了一个接口。所有的类都能当做接口去实现。因此dart可使用implements或extends和with实现多继承。
- mixin关键字声明的类无法被继承、无法创建但可以当做接口实现,同抽象类。
- Dart对象私有属性在同dart文件可以访问,在不同dart文件中仅能通过set或get访问。
- Dart主构造函数只能有一个,方法名与类名相同,构造函数可以没有方法体;与java一样,dart默认有一个无参主构造函数,当存在其他构造函数时,该默认构造函数不存在。
- Dart可以有多个命名构造函数,方法名为“类名.方法名”,实例化时,可根据需求选择构造函数;子类继承没有无参主构造函数的父类,子类构造方法需要指定一个父类构造函数。
- 同Java,Dart中除构造方法外,其他方法若没有方法体,即为抽象方法,拥有抽象方法的类必为抽象类,抽象类不能实例化,继承抽象类的子类,若没有实现父类的抽象方法,该类也只能抽象类。
测试代码如下
class User {
String name;
String phone;
double _weight;
//dart私有属性get方法
double get weight => _weight;
//dart私有属性set方法
set weight(double value) {
_weight = value;
}
//同java一样,dart默认有一个没有参数的构造函数,自定义构造函数后,默认构造函数将失效,需要重新定义
User() {}
//重定向构造函数
User.point() : this();
//命名构造函数,dart只能有一个主构造函数,可以有多个从构造函数
User.init(String name, String phone, double weight) {
this.name = name;
this.phone = phone;
this._weight = weight;
}
User.formJson(Map map) {
name = map["name"];
phone = map["phone"];
_weight = map["_weight"];
}
}
//mixin修饰的的类,同抽象类
mixin Employee{
getEmloyeeInfo();
getEmloyeeAttendance(){
}
}
abstract class Admin extends User with Employee{
Admin.init(String name, String phone, double weight)
: this(name, phone, weight);
//dart构造函数可以没有方法体,
Admin(String name, String phone, double weight) {
this.name = name;
this.phone = phone;
this._weight = weight;
}
//同java,成员方法若没有方法体,该类仅能是抽象类
call();
}
class Boss extends Admin {
//子类默认调用父类无构造函数,若父类没有无参构造函数,则必须调用父类构造函数的其中一个
Boss.init(String name, String phone, double weight)
: super.init(name, phone, weight);
Boss(String name, String phone, double weight) : super(name, phone, weight);
//继承抽象类必须实现它的抽象方法,不然该类也只能是抽象类
@override
call() {
return null;
}
@override
getEmloyeeInfo() {
return null;
}
}
main() {
//同java以及es6实例化对象都使用“new关键字”
User user = new User()
//dart提供级联操作,对象成员进行多次操作
..name = "tokily"
//同一个dart文件中可访问对象私有属性
.._weight = 123456;
User user1 = new User.init("user", "phone", 11.1);
//抽象类不能实例化
//Admin admin=new Admin.init("admin", "phone", 11.1);
//print(admin.name);
}
7、泛型
- Dart泛型与java类似
示例代码如下
class Test<T>{
isString(T para){
return para is String;
}
}
main(){
int a=10;
Test test=new Test();
print(test.isString(a));
}
8、dart同步和异步
- dart同步和异步与es6基本相同,通过async声明需要异步执行的程序块,通过await声明需要等待执行的代码块
class Test {
updateData() {
Future.delayed(Duration(seconds: 2));
return "ok";
}
//async修饰的方法表示异步执行,程序执行到这里会交给其他线程处理,然后立即向下继续执行
Future<String> commitInfo() async {
String string = await updateData();
return string;
}
}
void main() {
Test test = new Test();
//调用
Future<String> result = test.commitInfo();
//注册监听
result.then((value) {
print(value);
});
//控制台会打印最后一行代码,之后再打印请求到的数据
print("last line");
}