
Hello Dart
Dart 语言与其他许多编程语言一样,以 main 函数作为程序的入口点。以下是一个简单的 "Hello Dart" 程序示例,展示了 Dart 语言的这一特点。
// 标准写法
void main(){print("Hello Dart");
}// 省略写法
main(){print("Hello Dart");
}// 简写
main()=>print("Hello Dart");
数据类型
Dart 是一种面向对象的编程语言,其中数字、布尔值、函数等均为对象。这些对象都继承自 Object 类,与 Java 有相似之处。因此,在 Dart 中,所有变量的默认值都是 null。该语言包含了多种内置数据类型,其中包括数值类型、布尔类型、字符串类型以及集合类型。
1、数字类型
在 Dart 中,数值类型用于表示整数和浮点数。Dart 提供了两种数值类型:
-  int: -  int 类型表示整数,它的取值范围通常与平台有关,但在 Dart VM 上,它至少可以表示 -2^63 到 2^63 - 1 范围内的值。 
-  int 类型的字面量可以是十进制、十六进制或八进制表示法。例如: -  十进制:123 
-  十六进制:0x123 或 0X123 
-  八进制:0o123 或 0O123 
 
-  
 
-  
-  double: -  double 类型表示64位双精度浮点数,符合 IEEE 754 标准。 
-  double 类型的字面量可以是一个小数点表示的数字,也可以是一个指数表示的数字。例如: -  小数点:123.45 
-  指数:1.23e2 或 1.23E2 
 
-  
 
-  
在 Dart 中,数值类型是强类型的,这意味着它们在编译时就会进行检查。如果你尝试将一个 int 类型的值赋给一个声明为 double 类型的变量,或者相反,你需要显式地进行类型转换。
int myInt = 42;
double myDouble = 3.14;
// 错误:不能直接将 int 赋值给 double
// myDouble = myInt;
// 正确:显式转换 int 为 double
myDouble = myInt.toDouble();
// 错误:不能直接将 double 赋值给 int
// myInt = myDouble;
// 正确:显式转换 double 为 int
myInt = myDouble.toInt();在进行数值运算时,Dart 会根据操作数的类型自动进行类型提升。例如,如果一个 int 和一个 double 进行运算,结果会是一个 double。
int a = 1;
double b = 1.0;
var c = a + b; // c 是 double 类型在 Dart 中,数值类型还可以进行常见的算术运算(如加、减、乘、除)和其他数学函数(如求平方根、取整等),这些功能主要通过 dart:math 库提供。
2、布尔类型
在 Dart 中,布尔类型(bool)用于表示逻辑值,它只有两个可能的值:true 和 false。布尔类型在条件语句、循环和其他需要逻辑判断的地方非常有用。 以下是关于 Dart 中布尔类型的一些关键点:
-  声明布尔变量: -  要声明一个布尔类型的变量,你可以在变量前加上 bool 关键字。 
-  布尔变量应该只被赋值为 true 或 false。 
 
-  
bool isTrue = true;
bool isFalse = false;-  布尔表达式: -  Dart 中的布尔表达式会产生一个布尔值,例如比较操作符(==、!=、>、< 等)、逻辑操作符(&&、||、!)和其他可以返回布尔结果的表达式。 
-  布尔表达式常用于 if、while、do-while、for 循环以及 ?: 三元操作符等结构中。 
 
-  
if (isTrue) {print('This is true.');
}
while (!isFalse) {print('This will loop until isFalse becomes true.');
}
-  布尔字面量: -  true 和 false 是 Dart 中的布尔字面量,它们是编译时常量。 
-  布尔字面量可以直接用于任何需要布尔值的地方。 
 
-  
-  类型转换: -  Dart 不会自动将非布尔值转换为布尔值,如果你需要将其他类型转换为布尔值,你需要显式地进行类型转换。 
-  使用 as bool 或 toDouble() 方法可以进行类型转换。 
 
-  
var myNumber = 0;
if (myNumber as bool) {print('This will not be printed because myNumber is not true.');
}
-  布尔值的使用: -  布尔值常用于条件判断,控制程序的流程。 
-  在 Dart 中,布尔值也可以用于逻辑运算,如 &&(逻辑与)、||(逻辑或)和 !(逻辑非)。 
 
-  
bool isAdult = age >= 18;
bool canVote = isCitizen && isAdult;
bool canDrive = age >= 16 || hasDriverLicense;3、字符串类型
在 Dart 中,字符串类型(String)用于表示一系列的字符序列。Dart 中的字符串是不可变的,这意味着一旦创建了一个字符串,你就不能更改它。如果你需要对字符串进行操作,你会得到一个新的字符串。 以下是关于 Dart 中字符串类型的一些关键点:
-  字符串字面量: -  Dart 支持单引号(')、双引号(")和三引号(""")来创建字符串字面量。 
-  单引号和双引号字符串是相同的,可以互相嵌套使用。 
-  三引号字符串用于创建多行字符串,可以包含换行符和引号,而不需要转义。 
 
-  
var s1 = 'Single quotes work well for string literals.';
var s2 = "Double quotes work just as well.";
var s3 = 'It\'s easy to escape the string delimiter.';
var s4 = "It's even easier to use the other delimiter.";
var s5 = '''
Triple quotes allow multiline string literals.
For example, this is a Haiku:The old pond,A frog jumps in—Kerplunk!
''';
-  字符串拼接: -  Dart 支持使用 + 运算符来拼接字符串。 
-  使用 ${expression} 形式的模板字符串可以进行字符串插值。 
 
-  
var s1 = 'Hello, ';
var s2 = 'world!';
var s3 = s1 + s2; // s3 是 'Hello, world!'var name = 'Bob';
var greeting = 'Hello, $name!'; // greeting 是 'Hello, Bob!'
var greeting2 = 'Hello, ${name.toUpperCase()}!'; // greeting2 是 'Hello, BOB!'-  字符串属性和方法: -  Dart 提供了丰富的内置属性和方法来操作字符串,例如获取长度、查找子字符串、替换字符串等。 
 
-  
var s = 'Dart is fun';
print(s.length); // 输出字符串的长度
print(s.isEmpty); // 检查字符串是否为空
print(s.isNotEmpty); // 检查字符串是否不为空
print(s.contains('fun')); // 检查字符串是否包含子字符串
print(s.substring(5, 9)); // 获取子字符串
print(s.startsWith('Dart')); // 检查字符串是否以特定字符串开头
print(s.endsWith('fun')); // 检查字符串是否以特定字符串结尾
print(s.indexOf('is')); // 查找子字符串的索引
print(s.toUpperCase()); // 将字符串转换为大写
print(s.toLowerCase()); // 将字符串转换为小写
print(s.replaceAll('fun', 'awesome')); // 替换字符串中的子字符串-  UTF-16 编码: -  Dart 中的字符串是以 UTF-16 编码的,这意味着它们可以表示 Unicode 字符。 
 
-  
var s = '👍 for Dart';
print(s.codeUnits); // 打印字符串的 UTF-16 编码单元
print(s.runes); // 打印字符串的 Unicode 码点-  多行字符串: -  使用三引号字符串可以创建包含换行符和引号的多行字符串,而不需要进行转义。 
 
-  
var s = '''
This is a
multi-line
string.''';4、集合类型
Dart 语言提供了三种主要的集合类型:List、Set 和 Map。这些集合类型用于存储和处理数据集合。下面是关于这些集合类型的详细说明:
-  List(列表): -  List 是一个有序的集合,它可以包含重复的元素。 
-  它的元素可以通过索引来访问,索引从 0 开始。 
-  List 可以是固定的长度(FixedLengthList)或可变的长度(GrowableList)。 
 
-  
var list = [1, 2, 3, 4]; // 创建一个可变的列表
List<int> fixedLengthList = List(4); // 创建一个固定长度的列表,初始值为 null
fixedLengthList[0] = 1; // 给列表的第一个元素赋值
fixedLengthList[1] = 2; // 给列表的第二个元素赋值-  List 提供了丰富的操作方法,如添加元素、移除元素、排序等。 
list.add(5); // 在列表末尾添加一个元素
list.insert(1, 6); // 在索引 1 的位置插入元素 6
list.remove(2); // 移除列表中第一个 2
list.sort(); // 对列表进行排序-  Set(集合): -  Set 是一个无序的集合,它不包含重复的元素。 
-  Set 提供了高效的成员检测操作。 
 
-  
var halogens = {'fluorine', 'chlorine', 'bromine', 'iodine', 'astatine'}; // 创建一个 Set
Set<String> names = Set.from(['Seth', 'Kathy', 'Lars']); // 使用 from 方法创建一个 Set-  Set 也支持一些操作方法,如添加元素、移除元素、判断是否包含某个元素等。 
halogens.add('xenon'); // 向集合中添加一个元素
halogens.remove('fluorine'); // 从集合中移除一个元素
print(halogens.contains('fluorine')); // 检查集合是否包含某个元素-  Map(映射): -  Map 是一个键值对集合,每个键都映射到一个值。 
-  键和值可以是任何类型的对象。 
-  Map 中的键是唯一的,而值可以重复。 
 
-  
var gifts = {'first': 'partridge', 'second': 'turtledoves', 'fifth': 'golden rings'}; // 创建一个 Map
Map<String, String> nobleGases = Map(); // 创建一个空的 Map
nobleGases['He'] = 'Helium'; // 向 Map 中添加一个键值对
nobleGases['Ne'] = 'Neon'; // 向 Map 中添加另一个键值对-  Map 提供了多种方法来操作键值对,如获取值、设置值、检查是否包含键等。 
print(gifts['first']); // 获取 Map 中的第一个元素
gifts['fourth'] = 'calling birds'; // 添加一个新的键值对
gifts.remove('second'); // 移除一个键值对
print(gifts.containsKey('second')); // 检查 Map 是否包含某个键
print(gifts.containsValue('partridge')); // 检查 Map 是否包含某个值5、其他类型
-  可空类型(Nullable): -  从 Dart 2.2 开始,Dart 引入了可空类型(nullable)的概念,允许变量可能为 null。 
-  使用 ? 后缀可以创建可空类型,例如 int? 表示可能为 null 的整数。 
-  可空类型提供了更强的类型检查,有助于减少运行时错误。 
 
-  
var maybeNull = null; // 可空整数
var definitelyNotNull = 42; // 非空整数-  不可空类型(Non-nullable): -  不可空类型(non-nullable)是默认类型,意味着变量不能为 null。 
-  你可以通过在类型后添加 ! 来指定变量为不可空类型。 
 
-  
var nonNull = 42; // 不可空整数
var nonNullable = 42!; // 非空整数-  泛型(Generics): -  Dart 支持泛型类型,允许你在定义集合类型(如 List、Set、Map)时指定类型参数。 
-  泛型类型使得集合可以存储不同类型的对象,增强了代码的复用性和灵活性。 
 
-  
var listOfStrings = List<String>(); // 创建一个泛型列表,存储字符串
var listOfInts = List<int>(); // 创建一个泛型列表,存储整数-  枚举(Enums): -  Dart 支持枚举类型,用于定义一组命名的常量值。 
-  枚举类型可以包含成员的值和属性,以及常量值。 
 
-  
enum Direction { north, south, east, west }-  符号(Symbols): -  符号(Symbol)是 Dart 中的一个特殊类型,用于表示 Dart 程序中声明的操作符或标识符。 
-  符号可以作为字符串使用,但它们是编译时常量,不能被更改。 
 
-  
var symbol = #mySymbol; // 创建一个符号-  动态类型(Dynamic): -  动态类型(dynamic)是一个特殊的类型,表示可以存储任何类型的对象。 
-  使用动态类型可以创建更灵活的代码,但它也会导致运行时错误,因为类型检查是在运行时进行的。 
 
-  
var dynamicVariable = 42; // 动态变量可以存储任何类型的对象变量和常量
在 Dart 语言中,常量和变量用于存储数据。Dart 提供了三种不同的声明方式:const、final 和 var,每种声明方式都有其特定的用途和规则。
var 关键字
-  var(变量): -  var 关键字用于声明一个变量,它可以被多次赋值,并在运行时被修改。 
-  var 声明的变量在运行时是可变的,它们的值在运行时被确定。 
-  var 变量可以是任何类型,包括数字、字符串、符号、集合等。 
 
-  
var name = 'Alice';
name = 'Bob'; // 可以改变变量的值final和const
-  const(常量): -  const 关键字用于声明一个常量,它必须在其初始化时被赋值。 
-  const 声明的常量在运行时是不可变的,它们的值在编译时被确定。 
-  const 常量可以是数字、字符串、符号或集合类型。 
 
-  
const pi = 3.14159;
const List<int> numbers = [1, 2, 3];-  final(最终变量): -  final 关键字用于声明一个最终变量,它必须在初始化时被赋值。 
-  final 声明的变量在运行时是不可变的,它们的值在编译时被确定。 
-  final 变量可以是数字、字符串、符号或集合类型。 
 
-  
final int number = 42;
final List<String> names = ['Alice', 'Bob', 'Charlie'];使用场景
-  使用 const 和 final 来声明那些在运行时不应该被改变的值。 
-  使用 var 来声明那些在运行时可能需要改变的值。 
// const 常量,用于不可变的值
const List<String> planets = ['Mercury', 'Venus', 'Earth', 'Mars'];// final 最终变量,用于不可变的值
final int age = 25;// var 变量,用于可变的值
var score = 0;
score += 10; // 可以改变变量的值流程控制
循环
for 循环:用于遍历集合、范围或对象的集合。
for (int i = 0; i < 5; i++) {print('数字: $i');
}while 循环:当给定的条件为真时,重复执行代码块。
int i = 0;
while (i < 5) {print('数字: $i');i++;
}do-while 循环:至少执行一次代码块,然后重复执行,只要给定的条件为真。
int i = 0;
do {print('数字: $i');i++;
} while (i < 5);判断
if-else 语句:根据条件执行不同的代码块。
int age = 18;
if (age >= 18) {print('成年了');
} else {print('未成年');
}if-else if-else 语句:根据多个条件执行不同的代码块。
int score = 85;
if (score >= 90) {print('优秀');
} else if (score >= 80) {print('良好');
} else {print('及格');
}Switch-case
switch 语句:根据不同的条件执行不同的代码块。
int dayOfWeek = DayOfWeek.monday;
switch (dayOfWeek) {case DayOfWeek.monday:print('今天是星期一');break;case DayOfWeek.tuesday:print('今天是星期二');break;default:print('今天是其他工作日');
}Break 和 continue
break 语句:立即退出当前的循环或 switch 语句。
for (int i = 0; i < 10; i++) {if (i == 5) break;print('数字: $i');
}continue 语句:跳过当前循环的剩余代码,并开始下一次循环迭代。
for (int i = 0; i < 10; i++) {if (i == 5) continue;print('数字: $i');
}运算符
Dart 语言支持多种运算符,包括算术运算符、比较运算符、逻辑运算符、赋值运算符、条件运算符和类型运算符。这些运算符用于执行基本的数学运算、比较值、构建条件语句等。
算数运算符
-  +:加法 
-  -:减法 
-  *:乘法 
-  /:除法 
-  %:取模(余数) 
-  ~/:整除 
-  ++ 和 --:自增和自减(前缀和后缀) 
-  -  和 +:负号和正号(一元运算符) 
 
-  
int a = 5;
int b = 3;
int c = a + b; // c 变为 8
int d = a - b; // d 变为 2
int e = a * b; // e 变为 15
int f = a / b; // f 变为 1
int g = a % b; // g 变为 2
int h = -a; // h 变为 -5
int i = +a; // i 变为 5比较运算符
-  ==:等于 
-  !=:不等于 
-  <:小于 
-  >:大于 
-  <=:小于 
-  =:大于等于 
-  is 和 is!:对象是否为某个类型 
-  is!:对象不是某个类型 
int a = 5;
int b = 3;
if (a == b) {print('a 和 b 相等');
}
if (a != b) {print('a 和 b 不相等');
}
if (a < b) {print('a 小于 b');
}
if (a > b) {print('a 大于 b');
}
if (a <= b) {print('a 小于等于 b');
}
if (a >= b) {print('a 大于等于 b');
}逻辑运算符
-  &&:逻辑与 
-  ||:逻辑或 
-  !:逻辑非 
bool isTrue = true;
bool isFalse = false;
if (isTrue && isFalse) {print('条件为假');
}
if (isTrue || isFalse) {print('条件为真');
}
if (!isTrue) {print('条件为假');
}位运算符
-  =:简单赋值 
-  +=、-=、*=、/=、%=、~/=:复合赋值 
int a = 5;
a += 3; // a 变为 8
a -= 2; // a 变为 6
a *= 2; // a 变为 12
a /= 2; // a 变为 6
a %= 3; // a 变为 0
a ~/= 2; // a 变为 3其它运算符
条件运算符(三元运算符)
-  condition ? expression1 : expression2 
int a = 5;
int b = 3;
int max = a > b ? a : b; // max 变为 5类型运算符
-  is 和 is!:检查对象是否为某个类型 
-  is!:检查对象不是某个类型 
var obj = new Object();
if (obj is String) {print('obj 是一个字符串');
} else if (obj is! Object) {print('obj 不是 Object 类型');
} else {print('obj 是 Object 类型');
}
var obj = new Object();
if (obj is String) {print('obj 是一个字符串');
} else if (obj is! Object) {print('obj 不是 Object 类型');
} else {print('obj 是 Object 类型');
}空安全运算符
Dart 语言在 Dart 2.0 版本中引入了空安全(Null Safety)特性,这极大地提高了代码的安全性和健壮性。空安全特性通过引入新的运算符和规则来确保代码不会因为 null 值而引发运行时异常。
void main() {List<int>? myList;myList = [1, 2, 3];// 使用 ?. 进行可空类型检查if (myList?.isNotEmpty ?? false) {print('列表不为空,长度为:${myList!.length}');} else {print('列表为空或长度为 0');}// 使用 ?. 进行链式可空类型检查String? greeting = 'Hello';String? name = 'World';String? fullGreeting = greeting?.toUpperCase() + ' ' + name!.toUpperCase() + '!';print(fullGreeting);// 使用 ! 进行非空类型断言List<int> fixedList = List<int>.from(myList!);fixedList.add(4);print(fixedList);// 使用 ?. 进行属性访问和索引访问List<int>? anotherList = [1, 2, 3];int? firstElement = anotherList?.first;if (firstElement != null) {print('第一个元素是:$firstElement');} else {print('列表为空,没有第一个元素');}
}级联操纵符
Dart 中的级联操作符(Cascade Operator)是一种特殊的语法结构,它允许你连续调用一个对象的方法或访问其属性。级联操作符由两个点 .. 组成,它可以与可空类型一起使用,以避免运行时异常。
void main() {Person person = Person(name: 'Alice', age: 25);// 使用级联操作符连续访问两个属性person..name = 'Bob'..age = 30;print(person.name); // 输出: Bobprint(person.age); // 输出: 30
}class Person {String name;int age;Person({required this.name, required this.age});
}函数
Dart 语言中的函数是第一类对象,这意味着它们可以作为参数传递给其他函数,也可以从其他函数返回。
可变参数列表
-  Dart 支持可变参数列表,允许你定义一个函数,它接受任意数量的参数。 
void printArgs(var ...args) {for (var arg in args) {print(arg);}
}printArgs('Hello', 'World', 'Dart');可选参数
-  Dart 函数可以有可选参数,这些参数在调用时可以不提供值。 
void printWithOptions(String message, {int index = 0, List<String> items = const []}) {print('Index: $index');print('Items: $items');print('Message: $message');
}printWithOptions(message: 'Hello, World!');命名参数
-  Dart 函数支持命名参数,这意味着你可以根据参数的名称来指定它们的值,而不是根据位置。 
void printWithNamedOptions(String message, {int index = 0, List<String> items = const []}) {print('Index: $index');print('Items: $items');print('Message: $message');
}printWithNamedOptions(message: 'Hello, World!', index: 0, items: ['one', 'two', 'three']);默认参数
-  Dart 函数可以有默认参数,这意味着如果你不提供参数的值,它会使用默认值。 
Function(int, int) add = (a, b) => a + b;print(add(1, 2));函数类型
-  Dart 支持函数类型,这意味着你可以定义一个类型,它表示一个函数。 
Function(int, int) add = (a, b) => a + b;print(add(1, 2));高阶函数
-  Dart 支持高阶函数,这意味着你可以定义一个函数,它接受另一个函数作为参数,或者返回一个函数。 
Function(Function(int)) compose = (f) => (a) => f(a);Function(int) g = (a) => a * 2;
Function(int) h = compose(g);print(h(3));匿名函数
-  Dart 支持匿名函数,这意味着你可以定义一个没有名称的函数。 
print((a, b) => a + b)(1, 2);异步函数
-  Dart 支持异步函数,这意味着你可以定义一个函数,它使用 async 和 await 关键字来处理异步操作。 
Future<void> asyncPrint(String message) async {print(message);
}await asyncPrint('Hello, World!');闭包
-  Dart 支持闭包,这意味着你可以定义一个函数,它捕获其定义时作用域内的变量。 
void main() {int counter = 0;Function updateCounter = () {counter++;};updateCounter();print(counter); // 输出: 1
}异常
Dart 语言提供了丰富的异常处理机制,包括 try-catch 语句、finally 块、异常类以及 assert 语句。这些机制帮助开发者处理程序执行过程中可能出现的错误和异常情况。
try-catch 语句:
-  try-catch 语句用于捕获并处理代码块中的异常。 
-  基本形式:try { ... } on ExceptionType catch (error) { ... } 
-  try 块中的代码如果遇到异常,会立即抛出异常,并跳转到 catch 块。 
-  catch 块用于处理异常,可以指定要捕获的异常类型。 
try {print(1 / 0); // 抛出异常
} on Exception catch (e) {print('捕获到异常:$e');
}finally 块:
-  finally 块在 try 块执行完毕后总是执行,无论是否发生异常。 
-  finally 块用于执行清理代码,如关闭文件、释放资源等。 
-  基本形式:try { ... } catch (error) { ... } finally { ... } 
try {print(1 / 0); // 抛出异常
} catch (e) {print('捕获到异常:$e');
} finally {print('清理代码执行');
}异常类(Exception Classes):
-  Dart 提供了许多内置的异常类,如 Exception、AssertionError、NullThrownError 等。 
-  你可以创建自己的异常类,并继承自 Exception 类。 
class CustomException extends Exception {CustomException(this.message);final String message;
}assert 语句:
-  assert 语句用于检查一个条件是否为真,如果条件为假,则会抛出一个 AssertionError。 
-  基本形式:assert(condition, message); 
-  assert 语句通常用于调试和测试代码。 
assert(1 != 0, '这是一个错误'); // 不会抛出异常
assert(1 == 0, '这是一个错误'); // 抛出 AssertionError
-  Dart语言特性: -  Dart 是一种现代的编程语言,由 Google 开发,用于构建快速、高效的应用程序。 
-  它具有可扩展的语法和丰富的库,支持快速开发和部署。 
-  Dart 支持多平台开发,可以编译为 Android、iOS、Web 和桌面应用程序。 
-  它具有丰富的类型系统,支持静态类型检查和类型推断。 
 
-  
-  Dart的一些重用概念: -  Dart 支持模块,允许你将代码组织成可重用的包。 
-  你可以使用 import语句来重用其他模块中的代码。
-  Dart 还支持继承和多态,允许你创建可重用的类和接口。 
 
-  
-  Dart中 **..**** 表示什么意思**:-  ..是 Dart 的级联操作符,用于连续调用一个对象的方法或访问其属性。
-  它简化了连续调用多个方法的代码,提高了代码的可读性。 
 
-  
-  Dart多任务是如何并行的: -  Dart 支持异步编程,通过 async和await关键字。
-  Dart 使用微任务队列来处理异步任务,允许你并发执行多个任务。 
-  Dart 还提供了 Future和Stream类,用于处理异步操作。
 
-  
-  Dart是值传递还是引用传递: -  Dart 是值传递,这意味着当你传递一个变量给函数时,实际上是传递了变量的值,而不是变量的引用。 
-  这意味着函数内部对变量的修改不会影响原始变量。 
 
-  
-  Dart支持闭包吗?: -  Dart 支持闭包,允许你定义一个函数,它捕获其定义时作用域内的变量。 
-  闭包在 Dart 中非常常见,它们可以作为参数传递给其他函数,也可以从其他函数返回。 
 
-  
-  说一下 **Future**:-  Future是 Dart 中的一个类,用于表示异步操作的结果。
-  Future对象可以包含多个值,它们在异步操作完成后才能访问。
-  Future支持链式调用,允许你连续调用多个异步操作。
 
-  
-  说一下 **Stream**:-  Stream是 Dart 中的一个类,用于表示一系列的事件或数据。
-  Stream对象可以包含多个值,它们在事件或数据到达时被触发。
-  Stream支持流操作,允许你处理连续到达的数据。
 
-  
