SizedBox.shrink()
if (provider.pageState == DataStatus.completed) BottomMenuWidget(),
Dart没有public
,protected
,private
关键字,私有变量以下划线开头
未初始化的变量的初始值为
null
,即使数字类型的初始值也是null
,因为在Dart中, everything is object!
dart的类实现call()方法可以像函数一样被调用
class WannabeFunction {
call(String a, String b, String c) => '$a $b $c!';
}
main() {
var wf = new WannabeFunction();
var out = wf("Hi","there,","gang");
print('$out'); // Hi there, gang!
print(wf.runtimeType); // WannabeFunction
print(out.runtimeType); // String
print(wf is Function); // false
}
main(){
List ls = ['aa','bb',3];
List ls2 = ['dongnao simon',true,123];
//闭包
Function weGame(List ls,func(a)){
for(int i=0;i<ls.length;i++){
ls[i] = func(ls[i]);
}
return (ls2)=>ls2+ls;
}
var weGame2 = weGame(ls, (a) =>a*2);
print(weGame2(ls2));
}
weGame2(ls2)相当于 weGame(ls, (a) =>a*2)(ls2)
闭包好处防止变量污染
参考
typedef MyOperator(int a, int b);
// 1.List转String
var list=<String>['a','b'];
String str=JsonEncoder().convert(list);
print(str);
// 2.String转回List
List<String>list1=<String>[];
for(var value in JsonDecoder().convert(str)){
print(value);
list1.add(value);
};
list1.forEach(print);
class D extends Person with A, B {
D(String name, num age) : super(name, age);
}
在 Dart 中本不可以实现多继承,利用 mixins 可实现类似多继承的功能。
示例:
class A {
String info = "this is A";
void printA() {
print("A");
}
void run() {
print("A Run");
}
}
class B {
void printB() {
print("B");
}
void run() {
print("B Run");
}
}
class Person {
String name;
num age;
Person(this.name, this.age);
printInfo() {
print('${this.name}----${this.age}');
}
void run() {
print("Person Run");
}
}
// 使用 with 关键字实现 mixins
class C with A, B {}
// 既继承自 Person 又 mixins A 和 B,with 后跟的类有顺序之分,后类的方法会覆盖前类的方法
class D extends Person with A, B {
D(String name, num age) : super(name, age);
}
void main() {
var c = new C();
c.printA(); // A
c.printB(); // B
print(c.info); // this is A
var d = new D('张三', 20);
d.printInfo(); // 张三----20
d.run(); // B Run
}
如果不希望变量被修改,可以使用 final 和 const 定义变量。
final 和 const 的区别就是在编译的时候 const 变量的值就是已经确定的,final不一定,可能需要运行的时候才能确定值。
final name = 'Bob';
const bar = 1000000;
print(5 / 2 == 2.5); // 结果是双浮点型
print(5 ~/ 2 == 2); // 结果是整型
第1步:声明库
library library_name
第2步:关联库
import 'library_name'
如果导入两个存在冲突标识符的库, 则可以为这两个库,或者其中一个指定前缀。
首先,定义一个库:loggerlib.dart,代码如下所示:
library loggerlib;
void log(msg){
print("Log method called in loggerlib msg:$msg");
}
接下来,将定义另一个库:webloggerlib.dart,代码如下所示:
library webloggerlib;
void log(msg){
print("Log method called in webloggerlib msg:$msg");
}
最后,导入带有前缀的库。
import 'loggerlib.dart';
import 'webloggerlib.dart' as web;
// prefix avoids function name clashes
void main(){
log("hello from loggerlib");
web.log("hello from webloggerlib");
}
Deferred loading (也称之为 lazy loading) 可以让应用在需要的时候再加载库。 下面是一些使用延迟加载库的场景:
要延迟加载一个库,需要先使用 deferred as 来导入:
import 'package:greetings/hello.dart' deferred as hello;
当需要使用的时候,使用库标识符调用 loadLibrary() 函数来加载库:
Future greet() async {
await hello.loadLibrary();
hello.printGreeting();
}
在一个库上你可以多次调用 loadLibrary() 函数。但是该库只是载入一次。
类似js的Promise,可以使用then、await两种方式获取结果
值得注意的是,这里捕获异常是catchError(区别于js的catch),完成是whenComplete(区别于js的finally)
Future.delayed(Duration(milliseconds: 1000)).then((value) {
print("结果:$value");
}).catchError((error) {
print('$error');
}).whenComplete(() {
print('代码执行完成');
});
try{
var result=await Future.delayed(Duration(milliseconds: 1000));
}catch(e){
}finally{
}
Future封装了delayed延迟任务
Future.delayed(Duration(milliseconds: 1), () {
});
异步等待用法,与js的promise如出一辙
void _onRefresh() async {
await Future.delayed(Duration(milliseconds: 1000));
refreshInfo();
}
Future的return:相当于Promise的resolve
Future的throw Exception:相当于Promise的reject
// 模拟一个网络请求
Future<String> getNetworkData() {
return Future<String>(() {
sleep(Duration(seconds: 3));
// throw Exception("我是错误信息");
return "我是请求到的数据";
});
}
可以使用then多次获取异步结果,也可以使用catchError多次捕获异常
main(List<String> args) {
print('start');
Future(() {
sleep(Duration(seconds: 3));
// throw Exception("第一次异常");
return '第1次网络请求的结果';
}).then((result) {
print('$result');
sleep(Duration(seconds: 3));
return '第2次网络请求的结果';
}).then((result) {
print('$result');
sleep(Duration(seconds: 3));
return '第3次网络请求的结果';
}).then((result) {
print('$result');
}).catchError((error) {
print(error);
});
print('end');
}
在类型安全上通常需要泛型支持, 它的好处不仅仅是保证代码的正常运行:
class BusinessBaseClass<T> {
void printStr(T str) {
print(str);
}
}
void main() {
var temp = BusinessBaseClass<double>();
temp.printStr(1); //1.0
}
封装上使用广泛
abstract class Cache<T> {
T getByKey(String key);
void setByKey(String key, T value);
}
通过extends关键字可以限制泛型类型
class SomeBaseClass {}
class BusinessBaseClass<T extends SomeBaseClass> {}
使用时
class Extender extends SomeBaseClass {}
void main() {
var temp = BusinessBaseClass<Extender>();
}
泛型也可使用在函数上,下面示例取列表中的第一个元素
T first<T>(List<T> ts) {
T tmp = ts[0];
return tmp;
}
yaml文件的dependencies添加依赖
async: 2.8.2
import 'package:async/async.dart';
/**
* @author zhanglei
* @version 1.0
* @created 2022/10/22
* @title 防抖
* @description
* @changeRecord 2022/10/18 modify by zhanglei
*/
class ActionUtil {
static Map, CancelableOperation> timeout = {};
// 防抖 所谓防抖,就是指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。
// 应用场景: 用户输入间隔多久后没有输入时进行检查
/**
* @desc 函数防抖
* @param func 函数
* @param wait 延迟执行毫秒数
* @param immediate true 表立即执行,false 表非立即执行
*/
static debounce(Function func, {int wait = 500, String key = 'default'}) {
if (timeout[key] != null) {
timeout.remove(key);
}
_myFuture() async {
Future.delayed(Duration(milliseconds: wait), () {
if (timeout[key] != null) {
func();
timeout.remove(key);
}
});
}
timeout[key] = CancelableOperation.fromFuture(_myFuture());
}
// 节流 所谓节流,就是指连续触发事件但是在 n 秒中只执行一次函数。节流会稀释函数的执行频率。
// 应用场景: 需要稀释执行效率的地方使用,例如懒加载的时候监听滚动条。
/**
* @desc 函数节流
* @param func 函数
* @param wait 延迟执行毫秒数
* @param immediate true 表示立即执行,false 表示非立即执行
*/
static int previous = 0;
static throttle(Function func, {int wait = 100, String key = 'default'}) {
int now = DateTime.now().millisecondsSinceEpoch;
if (now - previous > wait) {
func();
previous = now;
}
}
}
使用
ActionUtil.debounce((){
})