一.语法
认识dart
void main(){
print("Hello Dart");
}
函数调用
//声明函数
void printInteger(int Number){
print("Teh number is $Number"); //打印控制台
}
void main(){
var number =42; //声明动态变量
printInteger(number); //调用函数
}
注释
//单行注释
/*
多行注释
*/
///文档注释
二.变量与常量
变量
void main(){
//明确指定类型
int age = 18 ;
//不明确类型
var year = 2021;
dynamic birthday = 2001;
}
常量
void main(){
//常量
//编译能取到的值
const math = 10;
//运行能取到的值
final chinese = DateTime(year);
// 可以不用初始化
final a;
a=1;
}
三.数据类型
数字类型
void main(){
// 数字类型
// 整数
int a =1;
//浮点数
double b = 1.11;
// 数值类型
num c=1;
//类型转换
print(c.toString());
print(3.8.toInt()); //向下取整
// 四舍五入
print(3.1415926.round());
print(3.1415926.toStringAsFixed(4));
// 返回余数
print(10.remainder(4));
//数字比较 0:系统 1:大于 -1:小于
print(10.compareTo(12));
//返回最大公约数
print(12.gcd(18));
// 科学计数法
print(100000.toStringAsExponential(1));
}
字符类型
单双引号都可以
三个引号可以声明换行符号
void main() {
//字符类型
var str1 = 'hello World';
var str2 = "你好,世界";
String str3 = 'hello World';
String str4 = "你好,世界";
String str5 = '''Hello
World
''';
print(str5);
// 拼接字符串
print("$str1$str2");
// 字符串分割
print(str1.split(' '));
// 字符串裁剪
print(' abc '.trim());
//判断字符串为空
print(''.isEmpty);
//字符串替换
print(str1.replaceAll("World", "Dart"));
//支持正则替换
print('obj756ec645t'.replaceAll(RegExp(r'\d+'), '_'));
//通过正则匹配手机号
var isPhone = RegExp(r'^1\d{10}$');
print(isPhone.hasMatch('12000000100'));
// 查找字符串
print(str1.contains('e'));
print(str1.indexOf('e'));
}
判断类型
void main() {
// 声明变量类型
bool flag1 = true;
print(flag1);
bool flag2 = false;
print(flag2);
// 显式进行判断
var flag3;
if (flag3 == null) {
print("真");
} else {
print("假");
}
var n1 = 0 / 0;
print(n1);
print(n1.isNaN); // NAN非数字
print(n1.isFinite); //判断数字是否有限
print(n1.isInfinite); //判断数字是否无限
print(n1.isNegative); //判断数字是否为负数
}
List类型
void main() {
// 声明List -- 字面量
List l1 = ['1', 'a,', 'c', 2, 3];
print(l1);
List l2 = <int>[1, 2, 3]; //限制元素类型的声明方式
print(l2);
//通过构造函数的声明方式
var l3 = new List.empty(growable: true);
l3.add(1);
print(l3);
var l4 = new List.filled(3, 6);
print(l4);
//扩展运算符
var l5 = [0,...l4];
print(l5);
var l6;
var l7 = [7,...?l6];
print(l7);
//返回列表的长度
print(l1.length);
//列表的反转
print(l1.reversed);//不再是列表
print(l1.reversed.toList());
// 添加元素
l3.addAll([4,5,6]);
print(l3);
//删除元素
l3.remove(6);
print(l3);
//根据下标删除元素
l3.removeAt(1);
print(l3);
// 再指定位置添加元素
l3.insert(1, 9);
print(l3);
//清空列表
l3.clear();
print(l3.length);
print(l3.isEmpty);
//合并元素
List words = ['Hello','World'];
print(words.join('-'));d
}
遍历List
void main(){
var nums = [1,2,3];
// for循环进行遍历
for (var i = 0 ; i < nums.length ; i ++){
print(nums[i]);
}
// for ... in
for (var item in nums) {
print(item);
}
//forEach
nums.forEach((element) {
print(element);
});
var newNums = [];
for (var i = 0 ; i < nums.length;i++){
newNums.add(nums[i] * nums[i]);
}
print(newNums);
var newNums1 = nums.map((e){
return e*e;
});
print(newNums1.toList());
//where()返回符合条件的元素
//判断数字是奇数
bool isOdd(n) => n % 2 == 1;
var oddNum = nums.where((element) => isOdd(element));
print(oddNum.toList());
//使用any() 来检测是否有技术(至少一个)
print(nums.any(isOdd));
//使用every() 来判断是否都是奇数
print(nums.every(isOdd));
//扩展
var pairs=[[1,2],[3,4]];
var flattened = pairs.expand((element) => element).toList();
print(flattened);
// 折叠--对列表的元素做一个累计操作
int result = nums.fold(2, (p, element) => p * element); //2 * (1*2*3)
print(result);
}
Set类型
void main(){
// 字面量
// 集合 重复元素会被去掉 程序正常运行
var nums = <int> {1,2,3};
print(nums);
var fruits = new Set();
fruits.add('香蕉');
fruits.add('苹果');
fruits.add('橘子');
print(fruits);
print(fruits.toList());
List myNums = [1,2,3,3,4];
print(myNums.toSet());//可以将重复元素过滤
// 集合特有的操作
var caocao = new Set();
caocao.addAll(['张辽','司马昱','关羽']);
var liubei=new Set();
liubei.addAll(['关羽','张飞','诸葛亮']);
// 求交集
print(caocao.intersection(liubei));
//求并集
print(caocao.union(liubei));
// 求差集
print(caocao.difference(liubei));
//返回第一个
print(caocao.first);
//返回最后一个
print(caocao.last);
//集合不能下标
//清空集合
caocao.clear();
}
map类型
void main() {
// 字面量
var person = {'name': '张三', 'age': 20};
print(person);
// 构造函数
var p = new Map();
p['name'] = '李四';
p['age'] = 22;
print(p);
//访问属性
print(p['name']);
//判断 Map 中的 key 是否存在
print(p.containsKey('name'));
//判断 Map 中的 Value 是否存在
print(p.containsValue('李四'));
//赋值
//如果key不存在 我们才赋值
p.putIfAbsent('gender', () => '男');
print(p);
//存在,赋值
p.putIfAbsent('gender', () => '女');
print(p);
// 获取map中所有的key
print(p.keys);
//获取map中所有的values
print(p.values);
//根据条件进行删除
p.removeWhere((key, value) => key == 'gender');
print(p);
}
其他类型
void main() {
// 字面量
var person = {'name': '张三', 'age': 20};
print(person);
// 构造函数
var p = new Map();
p['name'] = '李四';
p['age'] = 22;
print(p);
//访问属性
print(p['name']);
//判断 Map 中的 key 是否存在
print(p.containsKey('name'));
//判断 Map 中的 Value 是否存在
print(p.containsValue('李四'));
//赋值
//如果key不存在 我们才赋值
p.putIfAbsent('gender', () => '男');
print(p);
//存在,赋值
p.putIfAbsent('gender', () => '女');
print(p);
// 获取map中所有的key
print(p.keys);
//获取map中所有的values
print(p.values);
//根据条件进行删除
p.removeWhere((key, value) => key == 'gender');
print(p);
}
四.运算符
地板除
void main() {
// 地板除
print(7 ~/ 4);
}
类型判断运算符
void main(){
//类型判断运算符
List list = [];
if (list is List) {
print('list is List');
} else {
print('list in not List');
}
if (list is! List) {
print('不是列表');
} else {
print('是列表');
}
}
避空运算符
void main(){
//避空运算符
print(1 ?? 3); //返回1
print(null ?? 12); //返回12
var foo;
print(foo ?? 0); //如果foo是Null,则返回0
var a;
if (a == null) {
a = 3;
}
a ??= 3;
print(a);
}
条件属性运算符
void main(){
// 条件属性运算符(保护可能为空的属性)
var m = new Map();
print(m.length);
var obj;
// print(obj.length)
print(obj?.length);
}
级链运算符
void main(){
// 级链运算符
Set s = new Set();
s.add(1);
s.add(2);
s.add(3);
s.remove(2);
print(s);
Set s1 = new Set();
s1
..add('a')
..add('b')
..add('c')
..remove('b');
print(s);
}
五.函数
函数声明
//直接声明
void printInfo(){
print('Hello,World');
}
//返回值与函数声明的类型一致
int getNum(){
return 1;
}
void main(){
// 调用函数
printInfo();
print(getNum());
//匿名函数
var myPrint=(value){
print(value);
};
List fruits = ['苹果','香蕉','猕猴桃'];
fruits.forEach(myPrint);
// lambda函数 箭头函数
// 只能写一条语句
fruits.forEach((element) =>print(element));
fruits.forEach((element) {print(element);});
// 立即执行函数
((int n){
print(n);
})(17);
}
参数函数
void main(){
// 必填参数
String userinfo(String name){
return '你好:$name';
}
String res = userinfo('张三');
print(res);
//可选参数
String userinfo1(String name,[dynamic age]){
return '你好:$name$age';
}
String res1 = userinfo1('张三',1);
print(res1);
String userinfo2(String name,[int age=0]){
return '你好:$name$age';
}
String res2 = userinfo2('张三');
print(res2);
// 命名函数
String userinfo3(String name,{int age=0}){
return '你好:$name$age';
}
//命名参数调用时,需要与声明时的形参一致
String res3 = userinfo3('张三',age:20);
print(res3);
//函数参数
var myPrint=(value){
print(value);
};
List fruits = ['苹果','香蕉','猕猴桃'];
fruits.forEach(myPrint);
}
六.作用域
var globalNum=100;
void main(){
printInfo(){
// 局部变量
var localNum=10;
localNum--;
print(localNum);
print(globalNum);//可以再函数作用域中,访问全局变量
}
// printInfo(localNum);// print(localNum);不能在全局作用域访问局部变量
//闭包
printInfo();
printInfo();
parent(){
var money = 1000;
return(){
money -= 100;
print(money);
};
}
var p =parent();
p();
p();
p();
}
七.异步函数
name: dart
environment:
sdk: ">=2.7.0 <3.0.0"
dependencies:
http: ^0.12.2
then
//https://httpbin.org/ip 返回ip地址
import 'package:http/http.dart' as http ;
import 'dart:convert';
Future getIPAddress(){
final url = 'https://httpbin.org/ip';
return http.get(url).then((response){
print(response.body);
String ip = jsonDecode(response.body)['origin'];
return ip;
});
}
void main(){
// 调用
getIPAddress()
.then((ip) =>print(ip))
.catchError((error) => print(error));
}
async
//https://httpbin.org/ip 返回ip地址
import 'package:http/http.dart' as http ;
import 'dart:convert';
Future getIPAddress() async {
final url = 'https://httpbin.org/ip';
final response = await http.get(url);
String ip = jsonDecode(response.body)['origin'];
return ip;
}
void main()async{
// 调用
try{
final ip = await getIPAddress();
print(ip);
}catch(error){
print(error);
}
}
八.类
类
//声明类
class Person{
// le==类的属性
String name = '张三';
//类的方法
void getInfo(){
print('我是'+name+'');
}
}
void main(){
//实例化类,然后得到一个对象
Person p = new Person();
print(p.name);
//访问类中的属性
p.getInfo();
// Dart 所有的内容都是对象
Map m = new Map();
//属性为扳手
// 方法为方块
print(m.length);
m.addAll({'name':'李四','age':20});
print(m.length);
}
类与对象
class Point{
// num x;
// num y;
num x=1,y=1;
// 声明普通构造函数
Point(){
print('我是默认构造函数,实例化时,我是第一个被调用');
//this访问外部
num x=2,y=2;
//当命名指向有歧义时,this不能省略
print(x+y);
print(this.x+this.y);
}
}
void main(){
Point();
}
构造函数
class Point{
num x,y;
Point(this.x,this.y);
//命名构造函数
Point.origin(){
x=0;
y=0;
}
//命名构造函数
Point.fromJson({x:0,y:0}){
this.x=x;
this.y=y;
}
}
void main(){
// 自动设置
Point p1 = new Point.origin();
print(p1.x);
// 手动设置
Point p2 = new Point.fromJson(x:6,y:6);
print(p2.x);
}
常量构造函数
class Point{
num x;
num y;
Point(this.x,this.y);
}
class ImmutablePoint{
// 属性必须通过final声明
final num x;
final num y;
//常量构造函数,必须通过const 声明
const ImmutablePoint(this.x, this.y);
}
void main(){
var p1 = new Point(1,2);
var p2 = new Point(1,2);
print(p1 == p2);//false 内存比较
print(p1);//ture
//常量构造函数可以当作普通构造函数使用
// new之后即被初始化, 可以省略
var p3 =ImmutablePoint(1, 2);
var p4 = ImmutablePoint(1, 2);
print(p3==p4);//false
//声明不可变对象,必须通过 const 关键字
var p5 = const ImmutablePoint(1, 2);
var p6 = const ImmutablePoint(1, 2);
print(p5==p6);
}
工厂构造函数
class Person {
String name;
static Person instance;
//工厂构造函数
factory Person([String name = '刘备']) {
// 工厂构造函数不能使用this
// print(this.name);
// 工厂不能实例化
if (Person.instance == null) {
// 第一次实例化
Person.instance = new Person.newSelf(name);
}
//非第一次实例化
return Person.instance;
}
//命名构造函数
Person.newSelf(this.name);
}
void main() {
// 实例化操作
Person p1 = new Person('关羽');
print(p1.name);
Person p2 = new Person('张飞');
print(p2.name);
print(p1 == p2);
}
九.访问修饰
被访问类
class Person {
String name;
//声明私有属性
num _money=100;
Person(this.name);
num getMoney(){
return this._money;
}
// 声明私有方法
void _wife(){
print('我是 $name 的老婆');
}
}
访问方法
import '被访问类.dart';
void main(){
var p = new Person('张三');
print(p.name);
// 访问私有属性
// 只有把单独的类抽取出去,私有属性和犯法才起作用
// print(p._money);
// 访问私有方法
// print(p._wife());
}
十.getter和setter
class Circle {
final double PI = 3.1415;
num r;
Circle(this.r);
// num area(){
// return this.PI*this.r*this.r;
// }
//使用get声明的方法不能有小括号
// Getter
num get area{
return this.PI*this.r*this.r;
}
// Setter
set setR(value){
this.r=value;
}
}
void main(){
var c = new Circle(10);
// print(c.area());
print(c.area);
c.setR=20;
print(c.area);
}
十一.初始化列表
class Rect{
int height;
int width;
// Rect(this.height,this.width);
// Rect([int height = 2,int wight = 10]){
// this.height=height;
// this.height=height;
// print('${this.height}--${this.width}');
// }
// 初始化列表
Rect() : height = 4,width=20{
print('${this.height}--${this.width}');
}
}
class Point {
double x,y,z;
Point(this.x,this.y,this.z);
// 初始化列表的特殊的用发(重定向构造函数)
Point.twoD(double x,double y):this(x,y,0);
}
void main(){
var r = new Rect();
// 实例化点
var p = new Point(1, 2, 3);
print(p.z);
var p2 = new Point.twoD(4, 5);
print(p2.z);
}
十二.static
import 'dart:io';
class Person{
static String name = '张三';
int age = 18;
static printInfo(){
//不能通过this关键字,访问静态方法
// print(this.name);
print(name);
// 静态方法不能访问非静态方法
// print(age);
// 静态方法,不能直接访问非静态方法
// printUserInfo();
}
printUserInfo(){
//非静态方法,可以访问静态属性
print(name);
print(age);
printInfo();
}
}
void main(){
print(Person.name);
print(Person.printInfo());
// 不能通过类名称,直接访问非静态方法
// print(Person.printUserInfo());
var p = new Person();
// 不能访问静态属性
// print(p.name);
print(p.printUserInfo());
}
十三.元数据
class Phone {
//这是旧版本的开机方法,会在将来的版本中移除
@deprecated
activate() {
print("激活");
turnOn();
}
turnOn() {
print('开机');
}
}
void main() {
var p = new Phone();
//方法修饰
p.activate();//运行在IDE中会有中划线
//正常显示
p.turnOn();
}
十四.继承
class Father{
String name='刘备';
num money = 100000;
}
class Son extends Father{
}
void main(){
var f = new Father();
print(f.name);
var s =new Son();
print(s.name);
print(s.money);
}
import 'main.dart';
class Son extends Father{
//子类不能访问访问父类私有方法
// print(_a);
num money=100;
@override
say() {
// 子类
print(money);
// 父类
print(super.money);
print("我是$name");
}
}
void main(){
var f = new Father();
print(f.name);
var s =new Son();
s.say();
print(s.name);
print(s.money);
}
十五.抽象类
//抽象类,西侧提供abstract 关键字声明
//抽象类中,可以有抽象方法,也可以没有抽象方法,一般来所,凑下类都有抽象方法。
abstract class Phone{
//声明抽象方法
void processor();//手机处理器
void camera();//手机的摄像头
void info(){
print('我是抽象类的普通方法');
}
}
class Xiaomi extends Phone{
// 普通类继承了抽象类,就必须实现抽象类所有的抽象方法
@override
void processor(){
print('骁龙888');
}
@override
void camera(){
print('三星摄像头');
//普通类中,不能有抽象方法
// void aaa();
}
}
class Huawei extends Phone{
// 普通类继承了抽象类,就必须实现抽象类所有的抽象方法
@override
void processor(){
print('骁龙990');
}
@override
void camera(){
print('三星摄像头');
}
}
void main(){
// 抽象类不能被实例化
// var p1 = new Phone();
Phone p = new Xiaomi();
p.info();
Xiaomi m = new Xiaomi();
m.processor();
Huawei h = new Huawei();
h.processor();
}
十六.接口
abstract class Processor{
String cores; //内核:2核心,4核心
arch(String name); //芯片制程 7nm.5nm
}
abstract class Camera{
String resolution;//分辨率 :10000万,3000万
brand(String name); //品牌:三星,徕卡 ,蔡司
}
//通过 普通类实现接口
class Phone implements Processor,Camera{
@override
String cores;
@override
String resolution;
@override
arch(String name) {
print('$name$cores芯片制成');
}
@override
brand(String name) {
print('$name$resolution相机品牌');
}
Phone(this.cores,this.resolution);
}
void main() {
Phone p = new Phone('4核', '3000万');
p.arch('5nm');
p.brand('三星');
}
十七.混入
class Father{}
// class MixinA extends Father{ //用作混入的类。不能继承除了 object 以外的其他类
// class MixinA extends Object{
class MixinA{
String name = 'MixinA';
//不能构造函数
// MixinA();
void PrintA(){
print('A');
}
void run(){
print('run');
}
}
mixin MixinB{
String name = 'MixinB';
void printB(){
print('B');
void run(){
print('run');
}
}
}
class MyClass with MixinA,MixinB{}
void main(){
var c= new MyClass();
c.PrintA();
c.printB();
// 当有重复属性方法会执行后面的
print(c.name);
c.run();
}
十八.泛型函数
import 'dart:html';
String getData(String value){
return value;
}
int getData1(int value){
return value;
}
getData2(value){
return value;
}
//泛型函数
T getData3<T>(T value){
return value;
}
getData4<T>(T value) {
return value;
}
T getData5<T>( value) {
return value;
}
void main(){
print(getData('hello'));
print(getData1(1));
print(getData2('Hello'));
print(getData2(1));
// 泛型
print(getData3('Hello'));
print(getData3(1));
print(getData3<String>('Hello'));
print(getData3<int>(1));
}
十九.泛型类
class CommonClass {
Set s = new Set<int>();
void add(int value) {
this.s.add(value);
}
void info() {
print(this.s);
}
}
//泛型类
class GenericsClass<T>{
Set s = new Set<T>();
void add(T value) {
this.s.add(value);
}
void info() {
print(this.s);
}
}
void main() {
CommonClass c = new CommonClass();
c.add(1);
//字符被限制
// c.add('2');
c.info();
// 实例化泛型类
GenericsClass g = new GenericsClass<int>();
g.add(1);
//字符被限制
// g.add('2');
g.info();
GenericsClass g1 = new GenericsClass<String>();
g1.add('hello');
//字符被限制
// g1.add(1);
g1.info();
Set s = new Set();
s.add(1);
s.add("hello");
print(s);
// 字面量泛型
Set s1 = <String>{};
s1.add('hello');
//字符被限制
// c.add(1);
print(s1);
}
二十.泛型接口
abstract class ObjectCache{
getBykey(String key);
void setByKey(String key, Object value);
}
abstract class StringCache{
getBykey(String key);
void setByKey(String key, Object value);
}
//泛型接口
abstract class Cache<T>{
getBykey(String key);
void setByKey(String key, T 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}');
}
}
// 文件缓存
class FileCache<T> implements Cache<T> {
@override
getBykey(String key) {
return null;
}
@override
void setByKey(String key, T value) {
print('文件缓存: key=${key} value=${value}');
}
}
void main(){
// FileCache fc = new FileCache();
// fc.setByKey('too', 'bar');
FileCache fc = new FileCache<Map>();
fc.setByKey('too', {'name':"zhang"});
MemoryCache mc = new MemoryCache();
mc.setByKey('foo', {1,2,3,4});
}
二十一.泛型限制参数类型
class SomeBaseClass {
// ...
}
class Foo<T extends SomeBaseClass> {
String toString() => "Instance of 'Foo<$T>'";
}
class Extender extends SomeBaseClass {}
class AnotherClass {
// ...
}
void main() {
var someBaseClassfoo = Foo<SomeBaseClass>();
print(someBaseClassfoo);
var extenderFoo = Foo<Extender>();
print(extenderFoo);
var foo = Foo();
print(foo);
// 报错
// var f = Foo<AnotherClass>(); 类型不对
// print(f);
}
二十二.枚举
enum color { red, green, blue }
void main() {
//通过index返回枚举中具体常量的值
print(color.green.index);
// 通过values返回常量列表
print(color.values);
List<color> col = color.values;
print(col);
//通过下标访问列表中的内容
print(col[0]);
//通过foreach去遍历列表的内容
col.forEach((element) {
print('value:$element,index:${element.index}');
});
}
二十三.库
通过library来声明库
每个Dart文件默认都是一个库 只是没有使用Library来显示声明
建议写成小写字母+下划线的形式
library main;//默认隐藏了一个main的Library的声明
main(){
print('Hello World');
}
import来引入库
//自定义库
import 'lib/main.dart';
系统库
alt+鼠标库 可以查看源码
核心库默认会引入
import 'dart:math';
引入部分库
包含引入show
import 'lib/common.dart' show f1,f3;
排除引入hide
import 'lib/common.dart' hide f1,f3;
冲突库
import 'lib/f1.dart' as fun1;
//void func(){
// print('the is f1 func');
//}
import 'lib/f1.dart' as fun2;
//void func(){
// print('the is f1 func');
//}
//main.dart
void main(){
fun1.func();
fun2.func();
}
延迟加载库
import 'lib/f1.dart' deferred as func;
void main(){
func.hello();
print('1');
greet();
print('2');
print('3');
}
Future greet() async {
await func.loadLibrary();
func.func();
}
输出
1
2
3
Hello World
part 与 part of组装库
//home.dart
import 'util.dart';
void main(){
//来自sub1.dart
foo();
//来自sub2.dart
bar();
//来自util.dart
hello();
}
//util.dart
library util
part 'sub1.dart';
part 'sub2.dart';
String hello(){...}
//sub1.dart
part of util;
int foo(){}
//sub2.dart
part of util;
int bar(){}
第三方库
来源
项目结构
第三方库,必须包含一个pubspec.yaml
#项目名
name: dart
#项目描述
description: 描述
#当前包版本号
version: 1.0.0+1
#包发布位置
publish_to: 'none'
#dart版本环境
environment:
sdk: ">=2.7.0 <3.0.0"
#第三方库
dependencies:
http: ^0.12.2