前言
所有笔记均来自flutter实战,鉴于有kotlin基础,以kotlin为基准 .
小提示
print打印出的内容,在run命令栏中可以看到,杀死app重新打开在logcat中 筛选 tag:flutter 可看到。
一、基础变量
- 一看就懂
const a = "hello world"; //编译时直接替换为常量值
final b = "hello world"; //在第一次使用时被初始化
int? c; //类似kotlin的空安全类型
late int d; //类似kotlin的late
var e; //只有var没有val
-
一个java和kotlin从未有过的类型-动态类型dynamic
类似object的dynamic 动态类型,即在运行时确定类型。
和object不同的是dynamic声明的对象编译器会提供所有可能的组合,而Object声明的对象只能使用 Object 的属性与方法, 否则编译器会报错。
object a = "hello world"
print(a.length); // 报错 The getter 'length' is not defined for the class 'Object'
dynamic b = "hello world"
print(b.length);//正常
使用场景:
当无法确认一个变量的数据类型时,可以用,但是性能会有所损失且编译时不会进行类型检查,容易出问题,尽量不要用。
二、函数
- 记得写返回值类型哦
bool isNone(int atomicNumber) {//返回值boolean
return atomicNumber == 0;
}
isNone(int atomicNumber) {//返回值dynamic ,不是boolean
return atomicNumber == 0;
}
bool isNone (int atomicNumber) => atomicNumber==0 ;//简易写法
- 函数可以是变量,也可以将函数变为参数传递
void test(var callback) {
callback();
}
//将函数变为参数传递
test((){
print("afsf");
});
test(() => print("hi"));//简易写法
//变量=函数
var printstr = (str){
print(str);
};
test(printstr);
printstr(str){//简易写法
print(str);
}
test(printstr);
- 函数的可选参数
void say(String must, [String? choice,String? defaultvalue ="默认"]) {
print("$must 和 $choice and $defaultvalue");
}
say("必须");// 必须 和 null and 默认
say("必须","选择了");//必须 和 选择了 and 默认
say("必须","选择了","都给了");//必须 和 选择了 and 都给了
- 上面的可选参数不能像kotlin一样可选命名参数,就是只给defaultvalue赋值,跳过中间的choice ,那如何像kotlin一样呢?
void say(String must,{String? choice,String? defaultvalue ="默认"}) {
print("$must 和 $choice and $defaultvalue");
}
say("必须");// 必须 和 null and 默认
say("必须",choice:"选择了");//必须 和 选择了 and 默认
say("必须",defaultvalue: "都给了");//必须 和 null and 都给了
当然,这里没有kotlin的方便,因为不能同时使用3和4 ,也就是不能同时使用可选的位置参数和可选的命名参数
三、类
- 创建对象无需new
class A { A(); }
m(){
final a = A();
}
- 不可不会的mixin,有点像多继承。
mixin Eat{
eat(){
print('吃饭');
}
}
mixin Code{
eat(){
print('敲代码');
}
}
class MyApp extends StatelessWidget with Eat,Code {}
如果多个mixin 中有同名方法,with 时,会默认使用最后面的 mixin 的,mixin 方法中可以通过 super 关键字调用之前 mixin 或类中的方法
四、异步
这部分如果用过rxjava会好理解
- Future的基础使用
//等待多个异步任务都执行结束后才进行一些操作的示例
Future.wait([
// 2秒后返回结果
Future.delayed(const Duration(seconds: 2), () {
return "hello";
}),
// 4秒后返回结果
Future.delayed(const Duration(seconds: 4), () {
return " world";
})
]).then((results){
//成功
print(results[0]+results[1]);
}).catchError((e){
//失败
print(e);
}).whenComplete(() => {
//无论成功失败都会走到这里
});
- Future的链式调用,消除回调地狱
//先分别定义各个异步任务
Future<String> login(String userName) {
return Future.sync(() => "hello");
}
Future<String> getUserInfo(String pre) {
return Future.value("$pre world");
}
//链式使用
void loadData() {
login("hello").then((value) {
print(value);//输出hello
return value;
}).then((value) {
return getUserInfo(value); //返回的是一个getUserInfo
//如果是下面这样,那不会等待getUserInfo执行完才执行下一个then
// getUserInfo(value);
// return value;
}).then((value) {
print(value);//输出hello world
});
}
- async/await消除回调地狱
async用来表示函数是异步的,可以使用 then 方法添加回调函数
loadData() async {
try {
String pre = await login("hello").then((value) => "again hello");
String info= await getUserInfo(pre);
print("$info");//输出 again hello world
} catch (e) {
}
}
void test() {
loadData();
}
- stream
Stream 也是用于接收异步事件数据,和 Future 不同的是,它可以接收多个异步操作的结果(成功或失败)。在执行异步任务时,可以通过多次触发成功或失败事件来传递结果数据或错误异常。
Stream 常用于会多次读取数据的异步任务场景,如网络内容下载、文件读写等
Stream.fromFutures([
// 1秒后返回结果
Future.delayed(Duration(seconds: 1), () {
return "hello 1";
}),
// 抛出一个异常
Future.delayed(Duration(seconds: 2),(){
throw AssertionError("Error");
}),
// 3秒后返回结果
Future.delayed(Duration(seconds: 3), () {
return "hello 3";
})
]).listen((data){
print(data);
}, onError: (e){
print(e.message);
},onDone: (){
});
#上述代码依次输出:
hello 1 Error hello 3
后记
至此,基础的dart语言就学完啦✿✿ヽ(°▽°)ノ✿
网友评论