1. 变量声明
var text="hello world";//类型一旦确定,不能修改
///text=11;//运行会报错
///Dart 中所有类型都是Object的子类(包括Function和Null)
dynamic a = "aaa";
Object b = "bbbb";
a = 123;///后续可以赋值其他类型
b = 456;///后续可以赋值其他类型
```
print(a.length); // 正常,但是如果a不是字符串类型,调用这个属性的时候,运行时会报错
print(b.length);//这里会报错
```
dynamic与Object不同的是dynamic声明的对象编译器会提供所有可能的组合,而Object声明的对象只能使用 Object 的属性与方法
final和const
两者区别在于:const 变量是一个编译时常量(编译时直接替换为常量值),final变量在第一次使用时被初始化。被final或者const修饰的变量,变量类型可以省略
final str1="abc";
const str2="adb";
空安全机制
class Test {
///String str;//会报错,提示必须初始化,或者声明对象是可空的
///int b;//会报错,提示必须初始化,或者声明对象是可空的
String? str; //正常
Ink? i; //正常
Function? fun; //方法声明可空
show() {
String str2;//方法中声明不会报错
///print(str+"add");会提示报错
print("${str!}add");//加上!告诉编译器,它不为空。如果在此之前没有给它赋值,则运行会报错
}
}
2. 函数
void functionName(参数列表) {
// 函数体
}
int add(int a, int b) {
return a + b;
}
///对于单行函数
int square(int num) => num * num;
class Test {
///函数作为变量
var funName = (str) {
print(str);
};
///函数作为参数
void execute(var callback) {
callback();
}
///可选的位置参数
String info(String name, [int? age]) {
if (age != null) {
return "$name,$age";
} else {
return name;
}
}
///可选的命名参数
String infoTwo(String name, {int? age}) {
if (age != null) {
return "$name,$age";
} else {
return name;
}
}
text() {
execute(() => print("xxx"));
info("张三");
info("张三",18);
infoTwo("李四");
infoTwo("李四",age: 18);
}
}
3. 类
Dart 不支持多继承的,但是它支持 mixin,mixin 可以 “组合” 多个类
class Person {
say() {
print('say');
}
}
mixin Eat {
eat() {
print('eat');
}
}
mixin Walk {
walk() {
print('walk');
}
}
mixin Code {
code() {
print('key');
}
}
class Dog with Eat, Walk{}
class Man extends Person with Eat, Walk, Code{}
extension关键字
// 定义一个接口
abstract class GetInterface {
// 接口中的方法
void doSomething();
}
// 实现接口的类
class GetImplementation implements GetInterface {
@override
void doSomething() {
print('Doing something...');
}
}
// 定义一个扩展
extension GetExtension on GetInterface {
// 扩展方法
void doSomethingElse() {
print('Doing something else...');
}
}
void main() {
// 创建接口的实现实例
GetInterface getInstance = GetImplementation();
// 调用接口中的方法
getInstance.doSomething(); // 输出: Doing something...
// 由于扩展,现在可以调用额外的扩展方法
getInstance.doSomethingElse(); // 输出: Doing something else...
}
4. 异步
1、Future
Future.delayed(Duration(seconds: 2),(){
return "hi world!";
}).then((data){
print(data);
});
Future.delayed(Duration(seconds: 2),(){
//return "hi world!";
throw AssertionError("Error");
}).then((data){
//执行成功会走到这里
print("success");
}).catchError((e){
//执行失败会走到这里
print(e);
});
Future.delayed(Duration(seconds: 2), () {
//return "hi world!";
throw AssertionError("Error");
}).then((data) {
print("success");
}, onError: (e) {//跟catchError函数类似
print(e);
}).whenComplete((){
//无论成功或失败都会走到这里
});
///等待多个结果一起返回
Future.wait([
// 2秒后返回结果
Future.delayed(Duration(seconds: 2), () {
return "hello";
}),
// 4秒后返回结果
Future.delayed(Duration(seconds: 4), () {
return " world";
})
]).then((results){
print(results[0]+results[1]);
}).catchError((e){
print(e);
});
2 async/awit
//先分别定义各个异步任务
Future<String> login(String userName, String pwd) {
//用户登录
return Future.delayed(Duration(seconds: 2), () {
//模拟接口调用
return "{token:xxxx}";
});
}
Future<String> getUserInfo(String token) {
//获取用户信息
return Future.delayed(Duration(seconds: 2), () {
//模拟接口调用
return "{name:张三}";
});
}
Future saveUserInfo(String userInfo) {
// 保存用户信息
return Future.delayed(Duration(seconds: 2), () {
//模拟接口调用
return "保存用户信息";
});
}
test(){
//使用Future
login("username","******").then((id){
return getUserInfo(id);
}).then((userInfo){
return saveUserInfo(userInfo);
}).then((e){
//执行接下来的操作
}).catchError((e){
//错误处理
print(e);
});
task();
}
//使用 async/await
task() async {
try{
String token = await login("username","******");
String userInfo = await getUserInfo(token);
await saveUserInfo(userInfo);
//执行接下来的操作
} catch(e){
//错误处理
print(e);
}
}
3 Stream
可以接收多个异步操作的结果(成功或失败)。 Stream 常用于会多次读取数据的异步任务场景,如网络内容下载、文件读写等
示例一,每秒发送一个数字
//每秒发出一个数字
Stream<int> stream = Stream.periodic(const Duration(seconds: 1), (count) => count);
stream.listen((data) {
print('Received: $data');
}, onError: (error) {
print('Error: $error');
}, onDone: () {
print('Stream is done');
});
示例二,读取文件
void main() async {
// 假设我们有一个文本文件名为data.txt
final filePath = 'data.txt';
// 创建文件的Stream
Stream<List<int>> fileStream = File(filePath).openRead();
// 使用utf8.decoder将字节流转为字符串流
Stream<String> stringStream = fileStream.transform(utf8.decoder);
// 使用lines方法将字符串流转为逐行读取的流
Stream<String> lineStream = stringStream.transform(LineSplitter());
// 监听每一行数据
lineStream.listen((line) {
print('Read line: $line');
}, onError: (error) {
print('Error reading file: $error');
}, onDone: () {
print('Done reading file.');
});
}