Dart 之数据类型

232 阅读6分钟

Dart之数据类型.png

前言

想象一个场景,假如你正在一个超级市场里购物,你需要用不同的“容器”来装你购买的商品,因为每种商品的大小、形状和性质都不同。同样地,在编程中,数据类型就像是这些“容器”,它们用来存储和管理不同类型的数据。

一、基本数据类型

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 可以表示非常大或非常小的数值,包括正负无穷大正负0NaN(非数字)
  • 精度损失: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 数据类型分为基本数字类型、集合类型和特殊类型三大类,涵盖整数、浮点数、布尔值、字符串以及列表、映射和集合等。正确的选择数据类型对编写高效、可靠代码至关重要。