Flutter小白实操之Dart简介

2023-05-25  本文已影响0人  WeeverLu

以下内容参考《Flutter实战·第二版》,仅为个人学习、熟悉Dart语言,不同版本可能有稍微不一样。

///
/// 例子来源:
/// 《Flutter实战·第二版》https://book.flutterchina.club/chapter1/dart.html
///
/// 环境:
/// Flutter 3.10.1 • channel stable • https://github.com/flutter/flutter.git
/// Framework • revision d3d8effc68 (7 days ago) • 2023-05-16 17:59:05 -0700
/// Engine • revision b4fb11214d
/// Tools • Dart 3.0.1 • DevTools 2.23.1
///

调用

void main() {
  TestFunction().sayHi("aaa");
  TestFunction().doSomething(() => print("hhh"));
  TestFunction().say("A", "hello"); // A says hello
  TestFunction().say("A", "hello", "bus");// A says hello with a bus
  TestFunction().sayHello(who: "Bob"); // Bob say hello

  Dog()..eat()..walk();
  // flutter: eat
  // flutter: walk with 4 foot
  Dog().doSomething();
  // flutter: a Dog can do like this:
  // flutter: eat
  // flutter: walk
  // flutter: walk with 4 foot
  
  TestAsync().testFutureDelayed();
  TestAsync().testFutureWait();
  TestAsync().testAsync();
  TestAsync().testStream();
}

Var

class TestVar {
  void defVar() {
    var t = "hello, world!";
    // 下面代码在dart中会报错,因为变量t的类型已经确定为String,
    // 类型一旦确定后则不能再更改其类型。
    //t = 1000;
  }

  void dynamicAndObject() {
    // dynamic与Object声明的变量都可以赋值任意对象,且后期可以改变赋值的类型,这和 var 是不同的,如:
    dynamic t;
    Object x;
    t = "hello, world!";
    x = "hi, world!";
    //下面代码没有问题
    t = 1000;
    x = 1000;

    // dynamic与Object不同的是dynamic声明的对象编译器会提供所有可能的组合,
    // 而Object声明的对象只能使用 Object 的属性与方法, 否则编译器会报错,如:
    Object b = "";
    // 正常
    print(t.lenght);
    // 报错 The getter 'lenght' isn't defined for the type 'Object'.
    //print(b.lenght);

    // dynamic 的这个特点使得我们在使用它时需要格外注意,这很容易引入一个运行时错误,
    // 比如下面代码在编译时不会报错,而在运行时会报错:
    print(t.xx); // t是字符串,没有"xx"属性,编译时不会报错,运行时会报错
  }

  /// 一个 final 变量只能被设置一次,两者区别在于:
  /// const 变量是一个编译时常量(编译时直接替换为常量值),final变量在第一次使用时被初始化。
  void finalAndConst() {
    // 可以省略String这个类型声明
    // 有警告: Use 'const' for final variables initialized to a constant value.
    final str = "I am final String";
    // final String str = "I am final String";
    const str1 = "I am const String";
    // const String str2 = "I am const String";
  }

  void nullSafety() {
    // int i; // i = null
    // print(i*8); //运行时错误

    int i = 8; // 默认不空,定义后初始化
    int? j; // 可空,使用前判空

    // 使用late后续初始化,使用前必须初始化,否则报错
    late int k;
    // print(k); // The late local variable 'k' is definitely unassigned at this point.
    k = 9;
    print(k);

    // 如果一个变量我们定义为可空类型,在某些情况下即使我们给它赋值过了,但是预处理器仍然有可能识别不出,
    // 这时我们就要显式(通过在变量后面加一个”!“符号)告诉预处理器它已经不是null了,比如:
    Function? fun;
    if (i != null) {
      print(i! * 8); //因为已经判过空,所以能走到这 i 必不为null,如果没有显式申明,则 IDE 会报错
    }
    if (fun! != null) {
      fun!();
    }

    fun?.call(); // fun 不为空时则会被调用
  }
}

Function

可选参数[]和可选命名参数({xx,xx,...})还是不错的

class TestFunction {
  // 不指定返回类型,此时默认为dynamic,不是bool
  /*bool */isNoNull(String str) {
    return str.isNotEmpty;
  }
  // 简写
  bool isNull(String str) => str.isEmpty;

  // 函数作为变量
  var sayHi = (str) {
    print(str);
  };

  // 参数为函数
  void doSomething(var callback) {
    callback(); // 执行函数
  }

  // 用[]标记为可选的位置参数,并放在参数列表的最后面
  String say(String from, String msg, [String? device]) {
    var result = "$from says $msg";
    if (device != null) {
      result = "$result with a $device";
    }
    return result;
  }

  // 可选的命名参数,使用{param1, param2, …},放在参数列表的最后面,用于指定命名参数
  // 注意,不能同时使用可选的位置参数和可选的命名参数
  void sayHello({required String who}) {
    print("$who say hello");
  }
}

mixin

class Dog with Eat, Walk {
  @override
  walk() {
    print("walk with 4 foot");
  }

  doSomething() {
    print("a Dog can do like this: ");
    eat();
    super.walk();
    walk();
  }
}
class Man extends Persson with Eat, Walk, Code {}

class Persson {
  say() {
    print("say");
  }
}

mixin Eat {
  eat() {
    print("eat");
  }
}

mixin Walk {
  walk() {
    print("walk");
  }
}

mixin Code {
  code() {
    print("code");
  }
}

Async

class TestAsync {
  void testFutureDelayed() {
    print("Future.delayed 2s after exec something");
    Future.delayed(const Duration(seconds: 2), () {
      print("Future.delayed hello");
      throw AssertionError("delayed error"); // 根据是否有onError或catchError执行
    }).then((data) {
      // 成功走这里
      print("Future.delayed success");
    }, onError: (e) {
      print("Future.delayed onError $e"); // 加了onError,不走catchError
    }).catchError((e) {
      // 失败走这里 then没加onError,不走then,走catchError
      print("Future.delayed catchError $e");
    }).whenComplete(() {
      print("Future.delayed complete"); // 无论成功或失败都走这里
    });

    // flutter: Future.delayed 2s after exec something
    // flutter: Future.delayed hello
    // flutter: Future.delayed onError Assertion failed: "delayed error"
    // flutter: Future.delayed complete
  }

  // 等待多个异步任务都执行结束后才进行一些操作
  // Future.wait([]), 数组中所有Future都执行成功后,才会触发then的成功回调, 只要有一个Future执行失败,就会触发错误回调
  void testFutureWait() {
    print("Future.wait start after 4s show something");
    Future.wait([
      Future.delayed(const Duration(seconds: 2), () {
        return "Hi";
      }),
      Future.delayed(const Duration(seconds: 4), () {
        return " Bob";
      }),
    ]).then((results) {
      print("Future.wait ${results[0]}${results[1]}");
    }).catchError((e) {
      print(e);
    }).whenComplete(() {
      print("Future.wait complete");
    });

    // flutter: Future.wait start after 4s show something
    // flutter: Future.wait Hi Bob
    // flutter: Future.wait complete
  }

  void testAsync() {
    testAsync1();
    testAsync2();
    testAsync3();
    testAsync4();

    // flutter: testAsync1
    // flutter: testAsync2 pre //有await,after
    // flutter: testAsync3
    // flutter: testAsync4 pre //没有await,直接after
    // flutter: testAsync4 after //没等待
    //
    // flutter: testAsync2 in //等待2s后
    // flutter: testAsync2 after
    // flutter: testAsync4 in
  }

  void testAsync1() {
    print("testAsync1");
  }

  void testAsync2() async {
    print("testAsync2 pre");
    await Future.delayed(const Duration(seconds: 2), () {
      print("testAsync2 in");
    });
    print("testAsync2 after");
  }

  void testAsync3() {
    print("testAsync3");
  }

  void testAsync4() async {
    print("testAsync4 pre");
    /*await*/ Future.delayed(const Duration(seconds: 5), () {
      print("testAsync4 in");
    });
    print("testAsync4 after");
  }

  void testStream() {
    Stream.fromFutures([
      // 1秒后返回结果
      Future.delayed(const Duration(seconds: 1), () {
        return "Stream hi 1";
      }),
      Future.delayed(const Duration(seconds: 2), () {
        throw AssertionError("Stream error");
      }),
      Future.delayed(const Duration(seconds: 3), () {
        print("Stream hi 3");
      }),
    ]).listen((data) {
      print("Stream listen $data");
    }, onError: (e) {
      print("Stream error $e");
    }, onDone: () {
      print("Stream Done");
    });
    // flutter: Stream listen Stream hi 1
    // flutter: Stream error Assertion failed: "Stream error"
    // flutter: Stream hi 3
    // flutter: Stream listen null
    // flutter: Stream Done
  }
上一篇下一篇

猜你喜欢

热点阅读