Dart基础

65 阅读1分钟

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 的属性与方法

finalconst

两者区别在于: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.');
  });
}