简介
基于Dart语言,跨平台(移动端-Android-iOS/Web-各种浏览器/桌面-Windows-Mac/嵌入式平台-Linux-Fuchsia和高性能(GPU图形渲染技术)可达到120fps(胜任游戏)
flutter中文文档
Dart概述
Dart强类型的,面向对象的编程语言
运行方式一种是原生虚拟机,另一种是Dart转成js代码运行在浏览器
Dart与js对比,框架-生态-包管理命令
Dart官网 在线运行Dart代码
需要将Dart执行路径绑定在环境变量path上能够运行dart2js(转换js代码),pub(使用Dart生态相当于npm命令)等
Dart语法基础
运行dart helolo.dart
,Dart去执行文件中的main()函数
///文档注释,通过dartdoc转成md文档
变量-Dart万物皆对象,变量存储的是对象的引用
数据类型-Number,String,List,Map等
类型转换API例如1.toString() 10.compareTo(12)数字比较 ''.isEmpty判断是否为空
数据类型List
Set无序的,元素唯一的集合,有求交集、并集,差集的操作,不能通过下标来取值
Map无序键值对,可以有判断key和Value是否存在的方法
// 赋值
// 如果 key 不存在,我们才赋值(如果key已经存在,则不赋值)
p.putIfAbsent('gender', () => '男');
p.putIfAbsent('gender', () => '女');
// 获取 Map 中所有的 key
print(p.keys);
// 获取 Map 中所有的 value
print(p.values);
// 根据条件进行删除
p.removeWhere((key, value) => key == 'gender');
其他数据类型
运算符
## ~/ 地板除 向下取整
## is is! 类型判断运算符,类似js中instanceof
## null ?? 12 返回12,类似于js中||
## obj?.length 避空运算符和js同
## .. 级联运算符 原 s.add(1);s.add(2); 有后 s..add('a')..add('b') 返回运算符前对象的引用
函数
//js立即执行函数
(function() {
// 这里的代码在函数定义后立即执行
var localVar = 'This is a local variable';
})();
//Dart立即执行函数
((int n){
print(n);
}) (17);
//js箭头函数
var add = (a, b) => a + b;
//Dart箭头函数
int add(int a, int b) => a + b;
参数
位置参数
void greet(String name, int age) {
print('Hello, $name! You are $age years old.');
}
greet('Alice', 30); // 位置参数按顺序匹配
命名参数
在参数前面加上 {}
点击查看代码
void greet({String name, int age}) {
print('Hello, $name! You are $age years old.');
}
greet(name: 'Bob', age: 25); // 使用命名参数
可选位置参数
在参数前面加上 [] 来实现。可选位置参数可以有默认值。
点击查看代码
void greet(String name, [int age = 18]) {
print('Hello, $name! You are $age years old.');
}
greet('Charlie'); // 使用默认值
greet('David', 35); // 提供参数值
剩余参数
使用 ... 来标记剩余参数。剩余参数必须是一个列表,并且只能有一个
点击查看代码
void greet(String name, int age, {String greeting, ...otherInfo}) {
print('$greeting, $name! You are $age years old.');
otherInfo.forEach((info) => print(info));
}
greet('Emma', 28, greeting: 'Hi', otherInfo: ['Nice to meet you.', 'Have a nice day.']);
作用域和闭包
Dart中闭包的实现方式和javaScript中完全一致
使用时机,既能重用变量,又能保护变量不被污染
异步函数
Dart中异步函数通过Future来实现,async函数返回一个Future,await用于等待Future
Future<int> fetchNumber() async {
// 模拟异步操作
await Future.delayed(Duration(seconds: 2));
return 42;
}
//并行执行多个异步操作
void main() async {
await Future.wait([
fetchUserData(),
fetchPosts(),
]);
print('All async operations completed.');
}
类
类(包含属性和方法)是对象实例化的结果
构造函数是实例化时第一个被调用的函数,可在构造函数中写一些默认的操作
ES6和Dart中的类都支持构造函数,但在 Dart 中构造函数名称固定为类名,而在 ES6 中是 constructor。
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() {
var p = new Point(3, 4);
print(p.y);
// 默认坐标
Point p1 = new Point.origin();
// 手动设置坐标
Point p2 = new Point.fromJson(x: 6, y: 6);
}
//命名构造函数(类名.函数名)实现多个构造函数,提供清晰度
//常量构造函数(当类生成的对象不会改变时)类中所有都是常量不可变,性能提高,属性必须通过final声明,常量构造函数必须通过const声明,可以省略new关键字,但声明不可变对象必须通过const关键字
class ImmutablePoint {
// 属性必须通过 final 声明
final num x;
final num y;
// 常量构造函数,必须通过 const 声明
const ImmutablePoint(this.x, this.y);
}
void main() {
// // 声明不可变对象,必须通过 const 关键字
var p5 = const ImmutablePoint(1, 2);
var p6 = const ImmutablePoint(1, 2);
print(p5 == p6);//true
}
//工厂构造函数通过factory来声明,工厂函数不会自动生成实例,而是由代码来决定返回的实例
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('关羽');
Person p2 = new Person('张飞');
print(p1 == p2);//true
}
受保护的成员在继承类这个可以访问,private成员只能在内部类中访问
Dart要想私有,方法或属性需以_开头,并且只有把类单独抽离成一个文件,私有属性和方法才能起作用
使用getter声明的方法,访问和声明时都不需要小括号,访问setter声明的方法时,也不需要小括号
初始化列表构造函数中参数设置默认值,且不需要给this的变量赋值,特殊用法重定向构造函数,构造函数的参数动态
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
静态成员可以通过类名直接访问,不能通过实例化
静态方法不能使用this关键字,不能访问非静态的属性和方法
元数据
继承
子类extends继承父类,@override来覆写子类中与父类同样方法,super关键字在子类中来引用父类中属性和普通构造函数和命名构造函数Son(String job):super(job)
抽象类
模板,只能被继承,不能被实例化,继承的子类中必须实现抽象类的所有抽象方法,抽象方法是只有函数头没有函数体的方法,抽象类作为接口,继承的类需要实现所有的属性和方法
接口
接口可以是任意类,一般使用抽象类,implements 类可以实现多个接口,相当于组装零件
混入(Mixin)
Dart不同于C++只能继承单个类,普通类通过with来混入,提高代码复用的效率,后引入的混入会覆盖之前混入的内容,一旦被当做Mixin的类无法继承别的类只能继承Object类,也不能拥有构造函数
泛型
是在函数、类、接口中指定宽泛数据类型的语法,泛型函数、泛型类、泛型接口
使用泛型可以减少重复的代码,写一个函数代表多个不同数据类型的函数
// 泛型函数
T getData<T>(T value) {
return value;
}
// 只约定参数类型,不约定函数返回值的类型
getData<T>(T value) {
return value;
}
// 调用泛型函数
print(getData<int>(20));
// 泛型类
class GenericsClass<T> {
Set s = new Set<T>();
void add(T value) {
this.s.add(value);
}
void info() {
print(this.s);
}
}
// 实例化泛型类
GenericsClass g = new GenericsClass<int>();
g.add(1);
g.add(2);
g.info();
泛型类型进一步做了限制
class Foo<T extends SomeBaseClass> {
String toString() => "Instance of 'Foo<$T>'";
}
枚举
有限数量的常量
enum Color { red, green, blue} List<Color> colors = Color.values;
Dart库和生态
Dart中的库
自定义库
1.定义和导出库:在Dart中,可以使用 library 关键字定义一个库,并通过 export 导出公共API。
// lib/math.dart
library math;//小写字母加下划线
int add(int a, int b) {
return a + b;
}
// main.dart
import 'lib/math.dart';
void main() {
print(add(2, 3)); // 输出: 5
}
系统库
引入方式import 'dart:库名称'
dart:core库是被默认引入
部分引入
// show 后面指定包含引入的内容
import 'lib/common.dart' show f1, f3;
// hide 会隐藏后面的内容
import 'lib/common.dart' hide f1, f3;
命名冲突 用as关键字
import 'lib/common.dart';
import 'lib/function.dart' as func; // 给库添加前缀,解决命名冲突问题
void main() {
f1();
func.f1();
}
延迟加载库,需要用deferred as ,并没有真正加载,需要真正使用时调用loadLibrary函数
import 'lib/function.dart' deferred as func;
void main() {
greet();
}
Future greet() async {
await func.loadLibrary();
func.hello();
}
通过part与part of来组装库,构建复杂库的时候使用
系统库列表
第三方库
pubspec.yaml详情