前言
想象一个场景,假如你正在一个超级市场里购物,你需要用不同的“容器”来装你购买的商品,因为每种商品的大小、形状和性质都不同。同样地,在编程中,数据类型就像是这些“容器”,它们用来存储和管理不同类型的数据。
一、基本数据类型
1.1 数字类型
1.1.1 数值类型(num)
num 是一个抽象类,它有两个子类:int和double。用于表示整数类型和浮点数类型。
- num 提供了许多的属性和方法,让数值操作变得更加方便与灵活。
- 例如:a.runtimeType; a.compareTo(b);
- 使用num定义一个变量时,会自动推断出变量的类型。
- 例如:num a = 10;// 推断为int类型。
void main() {
num a = 10;
num b = 12.5;
print(a); // 输出:10
print(a.runtimeType); // 输出:int
print(b); // 输出:12.5
print(b.runtimeType); // 输出:double
print(a.compareTo(b)); // 输出:-1 a小于b
}
1.1.2 整数类型(int)
int类由 abstract final 共同修饰,意味着不能定义 int 的子类,也不能用另一个类实现 int。这些限制是一种妥协,以牺牲继承或实现为代价来实现高性能。
-
在 32 位平台上支持 32 位有符号整数(-2^31 ~ 2^31 - 1),即-2,147,483,648 ~ 2,147,483,647之间的值。
-
在64位平台上支持64位有符号整数(-2^63 ~ 2^63 - 1),即-9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807之间的值。
-
大整数支持(BigInt):可以表示任意大小的整数(超出int范围时使用)。
-
随机整数:通过Random类实现。
示例:
import 'dart:math';
void main() {
// 大整数支持示例
BigInt a = BigInt.parse('1200000213231241431212133322222223');
print(a); // 输出:1200000213231241431212133322222223
print(a.runtimeType); // _BigIntImpl
// 随机整数示例
Random b = Random(); // 需要导入math库
print(b.nextInt(100)); // 0~99的随机整数,示例输出:61
}
1.1.3 浮点数类型(double)
double类与int类一样由 abstract final 共同修饰,不能定义 double 的子类,也不能用另一个类实现 double。这些限制是一种妥协,以牺牲继承或实现为代价来实现高性能。
- 取值范围:double 可以表示非常大或非常小的数值,包括正负无穷大、正负0、NaN(非数字)。
- 精度损失:double遵循IEEE754标准表示浮点数,某些情况下会出现精度丢失(可以使用
double.parse或者第三方库如decimal来提高精度)。 - 随机浮点数:通过Random类实现。
示例:
// 取值范围示例
void main() {
double a = 4;
print(a); // 输出:4.0
print(a.runtimeType); // 输出:double
// 特殊取值示例
print(double.infinity); // 正无穷大 输出:Infinity
print(double.negativeInfinity); // 负无穷大 输出:-Infinity
print(-0.0 == 0.0); // true
print(double.nan); // NaN 输出:NaN
}
// 精度损失示例
import 'dart:math'; // 使用math库处理精度问题
void main() {
double a = 0.1 + 0.3;
print(a); // 输出:0.30000000000000004 出现了精度损失
double b = 4;
b = (a * 10).round() / 10;
print(b); // 输出:0.3
}
// 随机浮点数示例
import 'dart:math';
void main() {
Random a = Random();
double b = a.nextDouble(); // 生成0-1之间的随机浮点数。
print(b); // 输出:0.11590227119041852
}
1.2 数字类型基本操作
1.2.1 基本运算
加、减、乘、除、整除、取模。
示例:
void main() {
num a = 4;
int b = 5;
print(a + b); // 输出:9
print(a - b); // 输出:-1
print(a * b); // 输出:20
print(a / b); // 输出:0.8 除结果为double类型
print(a ~/ b); // 输出:0 整除结果为int类型
print(a % b); // 输出:4
}
1.2.2 数值转换
- toDouble():将数值转换为double类型。
- toInt():将数值转换为int类型。
示例:
void main() {
int a = 4;
double b = 5.1;
print(a.toDouble()); // 输出:4.0
print(b.toInt()); // 输出:5
}
1.2.3 比较和检查
- compareTo(num other):比较两个数值,返回-1、0、1。
- isNegative:判断数值是否为负数。
- isEven:判断整数是否为偶数(仅使用于int)。
- isOdd:判断整数是否为奇数(仅使用于int)
示例:
void main() {
int a = 4;
double b = 7.8;
print(a.compareTo(b)); // 输出:-1
print(a.isNegative); // 输出:false
print(a.isEven); // 输出:true
print(a.isOdd); // 输出:false
}
1.2.4 数值范围
- abs():求绝对值。
- clamp(num lowerLimit, num upperLimit):将数值限制在指定范围内。
示例:
void main() {
int a = -10;
int b = a.abs();
print(b); // 输出:10
print(a.clamp(1,5); // 输出:5
}
1.2.4 数学函数
- ceil():向上取整。
- floor():向下取整。
- round():四舍五入。
- truncate():截断小数部分。
示例:
void main() {
num a = 5.834;
print(a.ceil()); // 输出:6
print(a.floor()); // 输出:5
print(a.round()); // 输出:6
print(a.truncate()); // 输出:5
}
1.3 布尔类型(bool)
- true : 真
- false : 假
- 例如: bool sex = true;
1.4 字符串类型(String)
- 它是UTF-16编码的字符序列。
- 字符串可使用单引号或双引号定义,支持多行字符串和字符串插值。
- 字符串在Dart中是不可变的,一旦创建,其内容不能被更改。
示例:
void main() {
String name = 'Dart';
String slogan = '''
I love $name
I love $name
'''; // 支持多行字符串 和 字符串插值
print(slogan);
}
输出: I love Dart
I love Dart
1.5 动态类型(dynamic)
- 表示任何类型的变量,编译器不会进行类型检查。
- 可在运行时存储任何类型的值,但是会失去类型安全性的优势。
- 使用 dynamic 可能会导致运行时错误,应谨慎使用。
- 示例:dynamic a = 5; a = "hello,Dart";
二、集合类型
2.1 列表(List)
- 有序集合,允许重复元素。
- 列表可以是固定长度或可变长度,支持多种操作如添加、删除、查找等。
示例:
void main() {
List<int> a = [1, 2, 2, 5, 9];
print(a); // 输出:[1, 2, 2, 5, 9]
List<String> b = ['Dart', 'Flutter', 'Android'];
print(b); // 输出:[Dart, Flutter, Android]
}
2.2 集合(Set)
- 无序集合,不允许重复元素。
- 集合提供了高效的成员检测和交集、并集等操作。
示例:
void main() {
Set<int> a = {1, 2, 2, 2, 4, 5};
print(a); // 输出:{1, 2, 4, 5}
}
2.3 映射(Map)
- 键值对集合。
- 映射中的键必须唯一,可通过键访问对应的值。
示例:
void main() {
Map<String,int> student = {'小明':5, '小红':2, '小敏':7};
print(student); // 输出:{小明: 5, 小红: 2, 小敏: 7}
}
三、特殊类型
3.1 函数类型(Function)
- 表示函数或方法。
- 支持匿名函数(闭包),可以在运行时创建和传递函数。
示例:
void main() {
void hello() => print('hello,Dart!');
Function a = hello;
a(); // 输出:hello,Dart!
}
3.2 枚举类型(enum)
- 定义一组命名的常量。
- 枚举提供了一种安全的方式定义有限集合的常量。
示例:
enum Color {red, green, yellow, blue}
void main() {
Color mycolor = Color.yellow;
print(mycolor); // 输出:Color.yellow
}
3.3 符号类型(Symbol)
- 表示Dart代码中的标识符。
- 主要用于反射(reflection)和元编程。
示例:
void main() {
Symbol mySymbol = #hello;
print(mySymbol); // 输出:Symbol("hello")
}
3.4 类型别名(typedef)
- 用于定义类型别名。
示例:
typedef mytype = int;
void main() {
mytype a = 10;
print(a); // 输出:10
print(a.runtimeType); // 输出:int
}
四、类型转换
4.1 隐式转换
- 某些情况下,Dart会自动进行类型转换。
示例:
void main() {
double a = 4; // 将int类型的4隐式转换为double类型
print(a); // 输出:4.0
print(a.runtimeType); // 输出:double
}
4.2 显式转换
- 使用 .toString()、.toInt()、.toDouble() 等方法进行类型转换。
示例:
void main() {
int a = 4;
double b = 4.5;
print(a.toDouble()); // 输出:4.0
String s = a.toString();
print(s); // 输出:4
print(s.runtimeType); // 输出:String
print(b.toInt()); // 输出:4
}
五、总结
Dart 数据类型分为基本数字类型、集合类型和特殊类型三大类,涵盖整数、浮点数、布尔值、字符串以及列表、映射和集合等。正确的选择数据类型对编写高效、可靠代码至关重要。