Dart 中的一些重要知识点,包括函数、运算符、控制流、异常、类、泛型、库和可见性、异步支持、生成器、可被调用的类、Isolate、typedefs、元数据、变量及重要关键词的详细解释。
变量 (Variables)
声明方式
-
var: Dart 提供了一种动态类型的变量声明方式,使用var时,编译器会根据赋值推断变量的类型,但类型一旦推断出来,就无法更改。dart 复制代码 var name = 'Dart'; // name 被推断为 String 类型 // name = 42; // 错误:无法将 int 赋值给 String -
dynamic: 使用dynamic时,变量的类型在运行时确定,可以随时改变类型。虽然提供了灵活性,但会失去编译时的类型检查。dart 复制代码 dynamic anything = 'Dart'; anything = 42; // 合法 -
Object: Dart 中所有类的基类。可以用于保存任何类型的值,但仍然保留一些类型安全性。dart 复制代码 Object anything = 'Dart'; anything = 42; // 合法
常量
-
final: 用于定义运行时常量。final变量只能赋值一次,且必须在运行时初始化。可以延迟初始化(如在构造函数中)。dart 复制代码 final name = 'Dart'; // 在第一次使用时初始化 final DateTime now = DateTime.now(); // 运行时常量 -
const: 用于定义编译时常量。const变量在编译时就必须初始化,且值不可变。dart 复制代码 const pi = 3.14159; // 编译时常量 const List<int> numbers = [1, 2, 3]; // 不可变列表
final 与 const 的异同
-
异同:
final变量可以在运行时初始化,而const变量必须在编译时初始化。const可以创建编译时的常量对象,final不能。const可用于构造函数,以创建不可变对象,而final则用于变量声明。
dart 复制代码 final now = DateTime.now(); // 合法 const now = DateTime.now(); // 非法,不能在编译时确定
函数 (Functions)
定义与调用
-
命名函数: Dart 中的函数可以有返回值类型和参数类型。
dart 复制代码 int add(int a, int b) { return a + b; } -
匿名函数 (Lambda 表达式) : 也称为闭包,匿名函数可以捕获范围内的变量。
dart 复制代码 var multiply = (int a, int b) => a * b; -
可选参数: Dart 支持位置可选参数和命名可选参数,可以为其提供默认值。
dart 复制代码 // 位置可选参数 String greet(String name, [String title = '']) { return 'Hello $title $name'; } // 命名可选参数 void printInfo({String? name, int? age}) { print('Name: $name, Age: $age'); } -
高阶函数: 函数可以作为参数传递给另一个函数,也可以作为返回值。
dart 复制代码 void printMessage(String Function(String) formatter, String message) { print(formatter(message)); } -
返回类型: 虽然 Dart 允许省略返回类型,但为了代码的清晰性和可维护性,通常建议显式指定返回类型。
运算符 (Operators)
算术运算符
-
常见运算符:
+,-,*,/(除法返回double),~/(整除),%(取余)。dart 复制代码 int a = 5; int b = 2; print(a ~/ b); // 结果为 2 print(a % b); // 结果为 1
关系运算符
-
比较运算符:
==,!=,>,<,>=,<=。这些运算符用于比较两个值,并返回bool类型。dart 复制代码 print(5 > 2); // true
逻辑运算符
-
逻辑与 (
&&) : 两个操作数都为真时,结果为真。 -
逻辑或 (
||) : 两个操作数中至少一个为真时,结果为真。 -
逻辑非 (
!) : 对布尔值取反。dart 复制代码 bool isAdult = age >= 18; if (isAdult && isStudent) { // do something }
位运算符
-
按位运算:
&,|,^,~(按位取反),<<(左移),>>(右移)。这些运算符操作的是二进制位。dart 复制代码 int x = 3; // 0011 int y = 5; // 0101 print(x & y); // 结果为 1 (0001) print(x | y); // 结果为 7 (0111)
赋值运算符
-
赋值与复合赋值:
=,+=,-=,*=,/=,%=,可以简化操作。dart 复制代码 int a = 10; a += 5; // a = 15 -
空值赋值运算符 (
??=) : 如果变量当前值为null,则赋予新值。dart 复制代码 String? name; name ??= 'Guest'; // name 被赋值为 'Guest'
类型运算符
-
is: 检查对象是否为特定类型。 -
as: 将对象强制转换为特定类型。 -
is!: 检查对象是否不是特定类型。dart 复制代码 if (obj is String) { print(obj.length); // Dart 知道 obj 是 String 类型 }
控制流 (Control Flow)
条件语句
-
if语句: 标准的条件判断。dart 复制代码 if (age > 18) { print('Adult'); } else if (age > 13) { print('Teenager'); } else { print('Child'); }
循环
-
for循环: 标准的迭代语法。dart 复制代码 for (int i = 0; i < 5; i++) { print(i); } -
for-in循环: 用于遍历集合。dart 复制代码 List<String> names = ['Alice', 'Bob', 'Charlie']; for (var name in names) { print(name); } -
while循环: 在条件为真时执行循环体。dart 复制代码 int count = 0; while (count < 5) { print(count); count++; } -
do-while循环: 先执行一次循环体,然后检查条件。dart 复制代码 int count = 0; do { print(count); count++; } while (count < 5);
Switch 语句
-
switch-case: 用于多分支判断,支持整数、字符串和枚举类型。需要注意每个case分支后要使用break,否则会继续执行后续分支。dart 复制代码 String command = 'OPEN'; switch (command) { case 'OPEN': print('Opening'); break; case 'CLOSE': print('Closing'); break; default: print('Unknown command'); }
异常 (Exceptions)
捕获与处理
-
try-catch: 用于捕获和处理异常。catch可以捕获异常对象 (e) 和堆栈跟踪 (stackTrace)。dart 复制代码 try { var result = 5 ~/ 0; } catch (e, stackTrace) { print('Caught an exception: $e'); print('Stack trace: $stackTrace'); } -
finally: 无论是否抛出异常,finally块中的代码都会执行,通常用于资源释放或清理操作。dart 复制代码 try { var result = 5 ~/ 0; } catch (e) { print('Caught an exception: $e'); } finally { print('This is always executed'); }
自定义异常
-
定义与抛出: Dart 允许你定义自定义异常类,实现
Exception接口。dart 复制代码 class MyException implements Exception { final String message; MyException(this.message); @override String toString() => 'MyException: $message'; } void test() { throw MyException('Something went wrong'); }
类 (Classes)
基础知识
-
定义类: Dart 是纯面向对象的语言,类是其基本构建块。类中可以包含字段、方法和构造函数。
dart 复制代码 class Animal { String name; int age; Animal(this.name, this.age); void speak() { print('$name makes a noise.'); } } -
构造函数: Dart 支持多种类型的构造函数,包括默认构造函数、命名构造函数、工厂构造函数。
dart 复制代码 class Point { int x, y; // 默认构造函数 Point(this.x, this.y); // 命名构造函数 Point.origin() : x = 0, y = 0; } var p1 = Point(10, 20); var p2 = Point.origin(); -
继承和多态: Dart 支持继承,使用
extends关键字。子类可以覆盖父类的方法。dart 复制代码 class Dog extends Animal { Dog(String name, int age) : super(name, age); @override void speak() { print('$name barks.'); } } -
抽象类和接口: Dart 中的抽象类使用
abstract关键字,不能实例化。任何类都可以实现接口,即使它并不显式声明为接口。dart 复制代码 abstract class Shape { void draw(); } class Circle implements Shape { @override void draw() { print('Drawing a circle'); } } -
混入 (Mixins) : 使用
with关键字可以实现类似多继承的功能,将一个类的功能混入另一个类。dart 复制代码 mixin Swimmer { void swim() { print('Swimming'); } } class Fish with Swimmer { // Fish 现在具有 swim() 方法 }
泛型 (Generics)
泛型类
-
定义泛型类: 泛型用于提高代码的重用性和类型安全性。可以定义泛型类来处理不同类型的数据。
dart 复制代码 class Box<T> { T value; Box(this.value); } var intBox = Box<int>(10); var strBox = Box<String>('Hello');
泛型方法
-
定义泛型方法: 泛型不仅限于类,还可以应用于方法,允许方法处理多种类型的数据。
dart 复制代码 T identity<T>(T value) { return value; } var result = identity<int>(42);
库和可见性 (Libraries and Visibility)
库与模块化
-
库: Dart 的库是模块化的基础。每个 Dart 文件都是一个库。通过
import指令导入库,使用export指令暴露库的部分或全部内容。dart 复制代码 import 'package:my_package/my_library.dart'; export 'src/my_helper.dart'; // 重新导出 -
可见性: 使用
_前缀标识库内私有成员(字段、方法或类)。这些成员只能在声明它们的库中访问。dart 复制代码 class MyClass { String _privateVar = 'private'; void _privateMethod() {} }
异步支持 (Asynchronous Support)
异步编程
-
Future: Dart 中的Future表示一个异步操作的结果。使用async和await可以简化异步代码的书写,使其更接近同步代码的风格。dart 复制代码 Future<String> fetchData() async { return 'Data fetched'; } void main() async { var data = await fetchData(); print(data); } -
Stream:Stream是一个异步序列,用于处理一系列异步数据(如事件流)。dart 复制代码 Stream<int> countStream(int max) async* { for (int i = 1; i <= max; i++) { yield i; } }
生成器 (Generators)
迭代器生成
-
同步生成器: 使用
sync*关键字创建同步生成器,生成一个可以被迭代的对象。dart 复制代码 Iterable<int> getEvenNumbers(int n) sync* { for (int i = 0; i <= n; i += 2) { yield i; } } -
异步生成器: 使用
async*生成异步流,产生异步数据。dart 复制代码 Stream<int> getAsyncEvenNumbers(int n) async* { for (int i = 0; i <= n; i += 2) { await Future.delayed(Duration(seconds: 1)); yield i; } }
可被调用的类 (Callable Classes)
-
实现
call方法: 在 Dart 中,类可以实现call方法,从而使类的实例可以像函数一样调用。这在需要函数对象的地方非常有用。dart 复制代码 class Adder { int call(int a, int b) => a + b; } var adder = Adder(); print(adder(2, 3)); // 输出 5
Isolate
-
并发编程: Dart 中的并发模型基于 Isolate。每个 Isolate 拥有自己的内存空间,不与其他 Isolate 共享内存。Isolate 之间通过消息传递进行通信。
dart 复制代码 import 'dart:isolate'; void isolateEntry(SendPort sendPort) { sendPort.send('Hello from isolate'); } void main() async { var receivePort = ReceivePort(); await Isolate.spawn(isolateEntry, receivePort.sendPort); receivePort.listen((message) { print('Received: $message'); }); }
Typedefs
-
类型别名: 使用
typedef可以为函数类型或复杂的泛型类型定义一个简短的别名。这可以使代码更加简洁和易于维护。dart 复制代码 typedef IntBinaryOperation = int Function(int, int); int add(int a, int b) => a + b; IntBinaryOperation operation = add;
元数据 (Metadata)
元数据注解
-
元数据: Dart 中的元数据以注解的形式存在,注解使用
@符号引导。常用的注解包括@override、@deprecated等。dart 复制代码 class MyAnnotation { final String description; const MyAnnotation(this.description); } @MyAnnotation('This is a custom annotation') void myFunction() { print('Function with annotation'); } -
内置元数据: Dart 提供了一些常见的内置元数据,如
@override用于标记覆盖的父类方法,@deprecated用于标记已弃用的功能。dart 复制代码 @deprecated void oldMethod() { print('This method is deprecated'); }重要关键词 (Keywords)
this
-
this关键字: 用于引用当前实例。通常用于区分实例变量和方法参数,或在构造函数中初始化实例变量。dart 复制代码 class MyClass { String name; MyClass(this.name); }
super
-
super关键字: 用于调用父类的构造函数、方法或访问父类的属性。在子类中可以通过super关键字来调用父类中被重写的方法或构造函数。dart 复制代码 class Parent { void sayHello() { print('Hello from Parent'); } } class Child extends Parent { @override void sayHello() { super.sayHello(); // 调用父类方法 print('Hello from Child'); } }
static
-
static关键字: 用于定义类级别的成员。静态成员属于类,而不是类的实例,可以通过类名直接访问。dart 复制代码 class MyClass { static int counter = 0; static void increment() { counter++; } } void main() { MyClass.increment(); print(MyClass.counter); // 输出 1 }
new
-
new关键字: Dart 使用new关键字来创建类的实例,尽管 Dart 允许省略这个关键字。dart 复制代码 var person = new Person('Alice', 30);
final
-
final关键字: 用于定义运行时不可改变的变量。final变量必须在运行时初始化,并且只能被赋值一次。dart 复制代码 final int number = 42;
const
-
const关键字: 用于定义编译时常量。const变量在编译时就必须赋值,并且不可更改。dart 复制代码 const double pi = 3.14159;
abstract
-
abstract关键字: 用于定义抽象类。抽象类不能被实例化,通常包含抽象方法,子类必须实现这些方法。dart 复制代码 abstract class Shape { void draw(); }
extends 和 implements
-
extends: 用于继承父类。子类继承父类的所有非私有成员。dart 复制代码 class Dog extends Animal { // Dog 类继承了 Animal 类的所有成员 } -
implements: 用于实现接口。类必须实现接口中所有的方法和属性。dart 复制代码 class Car implements Vehicle { @override void drive() { print('Driving'); } }
enum
-
enum关键字: 用于定义枚举类型。枚举类型表示有限的、固定数量的值集合。dart 复制代码 enum Color { red, green, blue } void main() { var favoriteColor = Color.blue; print(favoriteColor); // 输出 Color.blue }
assert
-
assert关键字: 用于在开发过程中进行调试检查。assert表达式为true时不做任何操作;如果为false,则抛出异常。dart 复制代码 void main() { int age = 18; assert(age >= 18, 'Age must be 18 or older'); }
总结
以上是 Dart 编程语言中的一些核心知识点的详细讲解,包括函数、运算符、控制流、异常处理、类、泛型、库和可见性、异步支持、生成器、可调用类、Isolate、typedefs、元数据、变量及重要的关键字。掌握这些知识点后,你将能够更好地理解和使用 Dart 进行开发。