赞
踩
Dart
是由谷歌开发的计算机编程语言,它可以被用于web、服务器、移动应用 和物联网等领域的开发。
Dart
诞生于2011年,号称要取代JavaScript
。但是过去的几年中一直不温不火。直到Flutter的出现现在被人们重新重视。要学Flutter的话我们必须首先得会Dart。
要在我们本地开发Dart
程序的话首先需要安装Dart Sdk
官方文档 https://dart.dev/get-dart
windows(推荐) http://www.gekorm.com/dart-windows/
mac 如果mac电脑没有安装brew这个工具首先第一步需要安装它: https://brew.sh/
brew tap dart-lang/dart
brew install dart
Dart
开发工具:
Dart
的开发工具有很多: IntelliJ IDEA
、 WebStorm
、 Atom
、Vscode
等
例如在Vscode
中配置Dart
第一个程序
main() {
print('hello dart');
}
dart
是一个强大的脚本类语言,可以不预先定义变量类型 ,自动会类型推倒。
dart
中定义变量可以通过var
关键字可以通过类型来申明变量。如下:
var str='this is var'; //不指定类型会自动推导为String
String str='this is var';//指定类型,同上
final 和 const修饰符
const值不变 一开始就得赋值,编译期要确定。
final 可以开始不赋值 只能赋一次 ; 它是运行时常量,即在运行时第一次使用前才初始化
永远不改量的量,建议使用final或const修饰它,而不是使用var或其他变量类型。
Dart中支持以下数据类型:
常用数据类型:
//字符串用单引号,或者多引号表示
var str1='this is str1';
var str2="this is str2";
//字符串的拼接
String str1='你好';
String str2='Dart';
print("$str1 $str2");
list的使用
//方式一:定义list,不限类型 var l1=["张三",20,true]; //方式二:定义list,限定类型 var l2=<String>["张三","李四"]; //定义一个空list var l3 = []; //定义一个固定长度的list var l4=List.filled(2, ""); //添加一个成员 l2.add("王五"); //list的长度 l2.length; //list 空判断 l2.isEmpty; l2.isNotEmpty; //倒序 l2.reversed; l2.reversed.toList(); //添加数组 l2.addAll(['桃子','葡萄']); //indexOf查找数据 查找不到返回-1 查找到返回索引值 l2.indexOf('苹果'); //删除元素 l2.remove('桃子'); //删除指定位置 l2.removeAt(1); List myList=['香蕉','苹果','西瓜']; myList.fillRange(1, 2,'aaa'); //修改 myList.fillRange(1, 3,'aaa'); myList.insert(1,'aaa'); //插入 一个 myList.insertAll(1, ['aaa','bbb']); //插入 多个 print(myList); List myList=['香蕉','苹果','西瓜']; var str=myList.join('-'); //list转换成字符串 print(str); var str='香蕉-苹果-西瓜'; var list=str.split('-'); print(list); List myList=['香蕉','苹果','西瓜']; for(var i=0;i<myList.length;i++){ print(myList[i]); } //使用forEach遍历 for(var item in myList){ print(item); } //或者 myList.forEach((value){ print("$value"); }); //map方法映射为新数组 List myList=[1,3,4]; var newList=myList.map((value){ return value*2; }); print(newList.toList()); //any的使用 List myList=[1,3,4,5,7,8,9]; var f=myList.any((value){ //只要集合里面有满足条件的就返回true return value>5; }); print(f); //where的使用 筛选 List myList=[1,3,4,5,7,8,9]; var newList=myList.where((value){ return value>5; }); print(newList.toList()); //every的使用 List myList=[1,3,4,5,7,8,9]; var f=myList.every((value){ //每一个都满足条件返回true 否则返回false return value>5; }); print(f);
map的使用
//第一种定义 Maps的方式
var person={
"name":"张三",
"age":20,
"work":["程序员","送外卖"]
};
//第二种定义 Maps的方式
var p=new Map();
p["name"]="李四";
p["age"]=22;
p["work"]=["程序员","送外卖"];
set与list相互转化
var s=new Set();
s.add('香蕉');
s.add('苹果');
print(s.toList()); //set转化为list
List myList=['香蕉','苹果','西瓜','香蕉','苹果','香蕉','苹果'];
var s=new Set();
s.addAll(myList); //list 转化为set, 去重
print(s);
map的使用
Map person={ "name":"张三", "age":20 }; var m=new Map(); m["name"]="李四"; print(person); //常用属性: Map person={ "name":"张三", "age":20, "sex":"男" }; print(person.keys.toList()); print(person.values.toList()); print(person.isEmpty); print(person.isNotEmpty); //常用方法: Map person={ "name":"张三", "age":20, "sex":"男" }; person.addAll({ "work":['敲代码','送外卖'], "height":160 }); print(person); person.remove("sex"); print(person); print(person.containsValue('张三'));
内置方法/函数:
print();
自定义方法:
自定义方法的基本格式:
返回类型 方法名称(参数1,参数2,...){
方法体
return 返回值;
}
自定义方法
//基本的自定义方法 int getNum(){ var myNum=123; return myNum; } //演示方法的作用域 void xxx(){ //在方法中定义方法,作用域仅限于本方法 aaa(){ print(getList()); print('aaa'); } aaa(); }
自定义方法参数
//普通参数 int sumNum(int n){ var sum=0; for(var i=1;i<=n;i++) { sum+=i; } return sum; } //定义一个带可选参数的方法 ,最新的dart定义可选参数需要指定类型默认值 String printUserInfo(String username,[int age=0]){ //行参 if(age!=0){ return "姓名:$username---年龄:$age"; } return "姓名:$username---年龄保密"; } //定义一个命名参数的方法,最新的dart定义命名参数需要指定类型默认值 String printUserInfo(String username, {int age = 0, String sex = '男'}) {//行参 if (age != 0) { return "姓名:$username---性别:$sex--年龄:$age"; } return "姓名:$username---性别:$sex--年龄保密"; } print(printUserInfo('张三', age: 20, sex: '未知')); //匿名方法 var fn=(){ print('我是一个匿名方法'); }; fn(); //把方法当做参数的方法 fn1() { print('fn1'); } //fn2方法 fn2(fn) { fn(); }
闭包
闭包: 函数嵌套函数, 内部函数会调用外部函数的变量或参数, 变量或参数不会被系统回收(不会释放内存)
闭包的写法:
函数嵌套函数,并return 里面的函数,这样就形成了闭包。
闭包的特点:
1.常驻内存 (全局变量的特点)
2.不污染全局 (局部变量的特点)
//闭包
fn() {
var a = 123; /*不会污染全局 常驻内存*/
return () {
a++;
print(a);
};
}
//在调用时,打印值会一直增加
var b = fn();
b();
b();
b();
函数的其他使用
箭头函数等
List list=['苹果','香蕉','西瓜'];
list.forEach((value){
print(value);
});
//注意和方法的区别: 箭头函数内只能写一条语句,并且语句后面没有分号(;)
list.forEach((value)=>print(value));
Dart
所有的东西都是对象,所有的对象都继承自Object
类。
Dart
是一门使用类和单继承的面向对象语言,所有的对象都是类的实例,并且所有的类都是Object
的子类
一个类通常由属性和方法组成。
Dart和其他面向对象语言不一样,Data中没有 public private protected这些访问修饰符合
但是我们可以使用_把一个属性或者方法定义成私有。
Dart中的静态成员:
1.使用static 关键字来实现类级别的变量和函数
2.静态方法不能访问非静态成员,非静态方法可以访问静态成员
class Person { //最新版本的dart中需要初始化不可为null的实例字段,如果不初始化的话需要在属性前面加上late late String name; late int age; //默认构造函数的简写 Person(this.name, this.age); Person.now() { print('我是命名构造函数'); } Person.setInfo(String name, int age) { this.name = name; this.age = age; } void printInfo() { print("${this.name}----${this.age}"); } } void main() { //命名构造函数的调用 var d=new DateTime.now(); //实例化DateTime调用它的命名构造函数 print(d); Person p1=new Person('张三', 20); //默认实例化类的时候调用的是 默认构造函数 Person p1=new Person.now(); //命名构造函数 Person p2 = new Person.setInfo('李四', 30); p2.printInfo(); }
Dart
中的类的继承:
1. 子类使用extends关键词来继承父类
2. 子类会继承父类里面可见的属性和方法 但是不会继承构造函数
3. 子类能复写父类的方法 getter和setter
class Person {
late String name;
late num age;
Person(this.name,this.age);
void printInfo() {
print("${this.name}---${this.age}");
}
}
class Web extends Person{
Web(String name, num age) : super(name, age){
}
}
继承方法的覆写
class Person { String name; num age; Person(this.name,this.age); void printInfo() { print("${this.name}---${this.age}"); } work(){ print("${this.name}在工作..."); } } class Web extends Person{ Web(String name, num age) : super(name, age); run(){ print('run'); } //覆写父类的方法 @override //可以写也可以不写 建议在覆写父类方法的时候加上 @override void printInfo(){ print("姓名:${this.name}---年龄:${this.age}"); } @override work(){ print("${this.name}的工作是写代码"); } } main(){ Web w=new Web('李四',20); w.printInfo(); w.work(); }
抽象类
extends抽象类 和 implements的区别:
接口
和Java一样,dart也有接口,但是和Java还是有区别的。
首先,dart的接口没有interface关键字定义接口,而是普通类或抽象类都可以作为接口被实现。
同样使用implements
关键字进行实现。一个类可以实现多个接口。
但是dart的接口有点奇怪,如果实现的类是普通类,会将普通类和抽象中的属性的方法全部需要覆写一遍。
而因为抽象类可以定义抽象方法,普通类不可以,所以一般如果要实现像Java接口那样的方式,一般会使用抽象类。
建议使用抽象类定义接口。
abstract class Db{ //当做接口 接口:就是约定 、规范 late String uri; //数据库的链接地址 add(String data); save(); delete(); } class Mysql implements Db{ @override String uri; Mysql(this.uri); @override add(data) { print('这是mysql的add方法'+data); } @override delete() { return null; } @override save() { // TODO: implement save return null; } remove(){ } } class MsSql implements Db{ @override late String uri; @override add(String data) { print('这是mssql的add方法'+data); } @override delete() { return null; } @override save() { return null; } } main() { Mysql mysql=new Mysql('xxxxxx'); mysql.add('1243214'); }
Dart特性mixins
mixins的中文意思是混入,就是在类中混入其他功能。
在Dart中可以使用mixins实现类似多继承的功能。
因为mixins
使用的条件,随着Dart版本一直在变,这里讲的是Dart2.x中使用mixins的条件:
class A { String info="this is A"; void printA(){ print("A"); } } class B { void printB(){ print("B"); } } class C with A,B{ } void main(){ var c=new C(); print(c is C); //true print(c is A); //true print(c is B); //true }
泛型
通俗理解:泛型就是解决 类 接口 方法的复用性、以及对不特定数据类型的支持(类型校验)
//定义泛型方法 T getData<T>(T value){ return value; } //泛型类 abstract class Cache<T> { getByKey(String key); void setByKey(String key, T value); } class FileCache<T> implements Cache<T> { @override getByKey(String key) { return null; } @override void setByKey(String key, T value) { print("我是文件缓存 把key=${key} value=${value}的数据写入到了文件中"); } } class MemoryCache<T> implements Cache<T> { @override getByKey(String key) { return null; } @override void setByKey(String key, T value) { print("我是内存缓存 把key=${key} value=${value} -写入到了内存中"); } } void main() { // MemoryCache m=new MemoryCache<String>(); // m.setByKey('index', '首页数据'); MemoryCache m = new MemoryCache<Map>(); m.setByKey('index', {"name": "张三", "age": 20}); }
在Dart中,库的使用时通过import关键字引入的。
library指令可以创建一个库,每个Dart文件都是一个库,即使没有使用library指令来指定。
Dart中的库主要有三种:
1、需要在自己想项目根目录新建一个pubspec.yaml
2、在pubspec.yaml文件 然后配置名称 、描述、依赖等信息
3、然后运行 pub get 获取包下载到本地
4、项目中引入库 import ‘package:http/http.dart’ as http; 看文档使用
库中类名冲突的解决
当引入两个库中有相同名称标识符的时候,如果是java
通常我们通过写上完整的包名路径来指定使用的具体标识符,甚至不用import都可以,但是Dart里面是必须import的。当冲突的时候,可以使用as关键字来指定库的前缀。
如下所示:
import 'lib/Person1.dart';
import 'lib/Person2.dart' as lib;
main(List<String> args) {
Person p1=new Person('张三', 20);
p1.printInfo();
lib.Person p2=new lib.Person('李四', 20);
p2.printInfo();
}
延迟加载
也称为懒加载,可以在需要的时候再进行加载。
懒加载的最大好处是可以减少APP的启动时间。
懒加载使用deferred as关键字来指定,
如下所示:
import 'package:deferred/hello.dart' deferred as hello;
greet() async {
await hello.loadLibrary();
hello.printGreeting();
}
异步的实现
async是让方法变成异步。
await是等待异步方法执行完成。
async和await
这两个关键字的使用只需要记住两点:
1.只有async方法才能使用await关键字调用方法
2.如果调用别的async方法必须使用await关键字
Null safety
以及可空类型 非空断言
Null safety
翻译成中文的意思是空安全。
? 可空类型
! 类型断言
示例如下:
String? username="张三"; // String? 表示username是一个可空类型
username=null;
print(username);
String? str="this is str";
str=null;
print(str!.length);
//类型断言: 如果str不等于null 会打印str的长度,如果等于null会抛出异常
identical
dart:core 库中identical 函数:检查两个引用是否指向同一个对象。
var o = new Object();
var isIdentical = identical(o, new Object()); // false, different objects.
isIdentical = identical(o, o); // true, same object
//const关键词在多个地方创建相同的对象的时候,内存中只保留了一个对象。
isIdentical = identical(const Object(), const Object()); // true, const canonicalizes
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。