Dart之数据类型
一、前言学习 Dart 数据类型时可以先想象一个超市。超市里有饮料、蔬菜、水果、零食、日用品。不同商品不能全部随便塞进同一个容器里鸡蛋需要防摔的盒子饮料需要瓶子散装糖果需要袋子冷冻食品需要冷柜。代码里的数据也是一样。数字、文字、真假、列表、集合、键值对、函数它们都有各自更适合的“容器”。这个容器在编程里就叫数据类型。数据类型不是为了增加记忆负担而是为了告诉 Dart这份数据是什么、能做什么操作、应该如何存储和检查。这一篇我们系统梳理 Dart 中常见的数据类型。二、一句话理解Dart 数据类型就是数据的分类规则它决定一个值能表示什么内容、能使用哪些方法、能参与哪些操作。简单说int适合整数。double适合小数。String适合文字。bool适合真假。List适合有顺序的一组数据。Set适合去重的一组数据。Map适合键值对数据。先知道每种类型解决什么问题再去记它的方法学习会轻很多。三、Dart 数据类型总览Dart 中的数据类型可以先分成四类分类常见类型主要作用基本数据类型num、int、double、bool、String、dynamic表示数字、真假、文本和动态值集合类型List、Set、Map存放一组数据特殊类型Function、enum、Symbol、typedef表示函数、枚举、符号和类型别名类型转换toString()、toInt()、toDouble()在不同类型之间转换这张表是本文的地图。接下来我们一类一类展开。四、基本数据类型基本数据类型是最常见、最基础的一组类型。写 Dart 时几乎每天都会用到。4.1 数字类型 numnum是 Dart 数字类型的父类型它下面有两个常见子类型int和double。void main() { num a 10; num b 12.5; print(a); // 10 print(a.runtimeType); // int print(b); // 12.5 print(b.runtimeType); // double }虽然变量声明的是num但 Dart 会根据具体值判断它实际是int还是double。可以这样理解num是数字的大箱子。int是整数小盒子。double是小数小盒子。num适合你只关心“这是数字”但暂时不关心它是整数还是小数的场景。4.2 整数类型 intint用于表示整数。void main() { int age 18; int count 100; print(age); print(count); }整数没有小数部分适合表示年龄、数量、页码、索引、次数等。Dart 里的int支持平台相关的整数范围。通常开发中不需要一开始就背范围但要知道如果数字特别大可以使用BigInt。void main() { BigInt bigNumber BigInt.parse(1200000213231241431212133322222223); print(bigNumber); print(bigNumber.runtimeType); }如果需要随机整数可以使用dart:math里的Random。import dart:math; void main() { Random random Random(); print(random.nextInt(100)); // 生成 0 到 99 的随机整数 }4.3 浮点数类型 doubledouble用于表示小数。void main() { double price 19.9; double score 98.5; print(price); print(score); }即使写成4如果变量类型是double输出时也会表现为小数形式。void main() { double value 4; print(value); // 4.0 print(value.runtimeType); // double }double还能表示一些特殊值void main() { print(double.infinity); // Infinity print(double.negativeInfinity); // -Infinity print(double.nan); // NaN }使用double时要知道一个重要点浮点数可能出现精度问题。void main() { double value 0.1 0.2; print(value); // 0.30000000000000004 }这不是 Dart 算错了而是浮点数在计算机中的表示方式决定的。涉及金额、精确小数时要格外谨慎。4.4 数字类型基本操作数字类型可以做加、减、乘、除、整除、取余。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 print(a ~/ b); // 0 print(a % b); // 4 }几个容易忽略的点/的结果是double。~/是整除结果是整数。%是取余常用于判断是否整除。数字也可以做类型转换void main() { int a 4; double b 5.1; print(a.toDouble()); // 4.0 print(b.toInt()); // 5 }数字可以比较和检查void main() { int a 4; double b 7.8; print(a.compareTo(b)); // -1表示 a 小于 b print(a.isNegative); // false print(a.isEven); // true print(a.isOdd); // false }常用数字方法还有void main() { int a -10; num b 5.834; print(a.abs()); // 10 print(a.clamp(1, 5)); // 1 print(b.ceil()); // 6 print(b.floor()); // 5 print(b.round()); // 6 print(b.truncate()); // 5 }这些方法可以这样记abs()求绝对值。clamp()把数限制在一个范围内。ceil()向上取整。floor()向下取整。round()四舍五入。truncate()直接截断小数部分。4.5 布尔类型 boolbool只有两个值true和false。void main() { bool isLogin true; bool isVip false; print(isLogin); print(isVip); }它常用于条件判断。void main() { bool hasTicket true; if (hasTicket) { print(可以入场); } else { print(不能入场); } }可以把bool理解成代码里的开关开是true关是false。4.6 字符串类型 StringString用于表示文本。void main() { String name Dart; String language Flutter; print(name); print(language); }Dart 字符串可以用单引号也可以用双引号。字符串支持插值也就是把变量嵌入字符串中。void main() { String name Dart; print(Hello, $name); }如果表达式比较复杂可以使用${}。void main() { int a 3; int b 5; print(结果是${a b}); }多行字符串可以使用三个引号。void main() { String slogan I love Dart I love Flutter ; print(slogan); }要注意Dart 中的字符串是不可变的。所谓修改字符串本质上通常是创建一个新的字符串。4.7 动态类型 dynamicdynamic表示这个变量可以存放任意类型的值。void main() { dynamic value 5; print(value); value hello, Dart; print(value); }看起来很灵活但也有代价编译器不会帮你做严格类型检查错误可能留到运行时才暴露。void main() { dynamic value 10; value hello; print(value.toUpperCase()); }如果你很确定数据结构优先使用明确类型。dynamic更适合处理临时不确定的数据比如外部接口返回、动态 JSON、迁移旧代码等。五、集合类型集合类型用于存放一组数据。如果基本类型像一个个商品那么集合类型就像购物袋、收纳盒和标签柜。5.1 列表 ListList是有顺序的集合允许重复元素。void main() { Listint numbers [1, 2, 2, 5, 9]; ListString skills [Dart, Flutter, Android]; print(numbers); print(skills); }List的特点有顺序。可以通过下标访问。允许重复。适合表示一串有序数据。void main() { ListString names [Tom, Jerry, Lucy]; print(names[0]); // Tom names.add(Lily); print(names); }如果你关心“第几个元素是什么”通常应该先想到List。5.2 集合 SetSet是不重复的集合。void main() { Setint numbers {1, 2, 2, 2, 4, 5}; print(numbers); // {1, 2, 4, 5} }Set的特点不允许重复元素。适合去重。适合判断某个元素是否存在。void main() { SetString tags {Dart, Flutter, Dart}; print(tags); // {Dart, Flutter} print(tags.contains(Dart)); // true }如果你关心“有没有重复”“是否包含某个值”通常可以考虑Set。5.3 映射 MapMap是键值对集合。void main() { MapString, int scores { 小明: 5, 小红: 2, 小敏: 7, }; print(scores); }Map的特点由 key 和 value 组成。key 必须唯一。可以通过 key 快速找到 value。void main() { MapString, int scores { Tom: 90, Jerry: 85, }; print(scores[Tom]); // 90 scores[Lucy] 100; print(scores); }如果你关心“通过一个名字找到对应数据”通常应该想到Map。5.4 List、Set、Map 怎么选三种集合很容易混在一起可以这样判断类型适合场景关键特点List商品列表、消息列表、步骤列表有顺序、可重复Set标签去重、唯一 ID 集合不重复Map用户信息、配置项、成绩表key-value简单记法要顺序用List。要去重用Set。要通过 key 查值用Map。六、特殊类型特殊类型不是每天都像String、int那样频繁出现但它们在 Dart 里也很重要。6.1 函数类型 Function在 Dart 中函数也可以作为值传递。void hello() { print(hello, Dart!); } void main() { Function fn hello; fn(); }这意味着我们可以把函数存到变量里也可以把函数作为参数传递。更推荐的写法是尽量写清楚函数类型。void main() { int Function(int, int) add (int a, int b) { return a b; }; print(add(3, 5)); }明确函数类型之后参数和返回值都会更清楚。6.2 枚举类型 enumenum用于定义一组固定的命名常量。enum Color { red, green, yellow, blue, } void main() { Color myColor Color.yellow; print(myColor); }枚举适合表示有限选项比如颜色、状态、方向、订单状态。enum OrderStatus { pending, paid, shipped, finished, }相比直接使用字符串枚举更安全。String status paidd; // 拼错了也可能不容易发现 OrderStatus orderStatus OrderStatus.paid;6.3 符号类型 SymbolSymbol用于表示 Dart 代码中的标识符。void main() { Symbol symbol #hello; print(symbol); // Symbol(hello) }普通业务代码里Symbol不算高频它更多出现在反射、元编程等场景中。初学阶段不需要深挖它只要知道#hello表示一个符号不是字符串。6.4 类型别名 typedeftypedef用于给类型起一个别名。最简单的例子typedef MyInt int; void main() { MyInt value 10; print(value); print(value.runtimeType); }不过实际开发中typedef更常用于函数类型别名。typedef Calculate int Function(int a, int b); int add(int a, int b) { return a b; } void main() { Calculate fn add; print(fn(3, 5)); }这样写可以让复杂函数类型更容易阅读。七、类型转换类型转换就是把一种类型的数据变成另一种类型。比如把整数变成小数把数字变成字符串把字符串解析成数字。7.1 隐式转换某些情况下Dart 会自动完成类型转换。最常见的是把int赋值给double。void main() { double value 4; print(value); // 4.0 print(value.runtimeType); // double }这里4原本是整数但赋值给double变量时会转换成4.0。不过不要以为 Dart 会随便帮你转。Dart 仍然是强类型语言很多转换需要你明确写出来。7.2 显式转换显式转换就是开发者主动调用方法转换类型。void main() { int a 4; double b 4.5; print(a.toDouble()); // 4.0 String text a.toString(); print(text); // 4 print(text.runtimeType); // String print(b.toInt()); // 4 }常见转换方法方法作用toString()转成字符串toInt()转成整数toDouble()转成小数int.parse()把字符串解析成整数double.parse()把字符串解析成小数字符串转数字示例void main() { String ageText 18; String priceText 19.9; int age int.parse(ageText); double price double.parse(priceText); print(age); print(price); }如果字符串格式不正确解析会报错。更稳的方式是使用tryParse()。void main() { String text abc; int? value int.tryParse(text); print(value); // null }tryParse()解析失败时返回null比直接抛异常更适合处理用户输入。八、常见误区8.1 以为 dynamic 更方便就到处用dynamic的确灵活但它会减少类型检查。void main() { dynamic value 10; value true; value hello; }这段代码能运行但如果后续调用了不存在的方法错误可能到运行时才出现。建议是能明确类型就明确类型不确定时再使用dynamic。8.2 混淆 List、Set、Map这三个集合类型不是谁替代谁而是解决不同问题。List解决顺序问题。Set解决去重问题。Map解决映射查找问题。写代码前先问自己我需要顺序、唯一性还是通过 key 找 value8.3 忽略 double 精度问题浮点数不适合直接用于所有精确计算。void main() { print(0.1 0.2); // 0.30000000000000004 }如果涉及金额、计费、精确小数要考虑更稳妥的处理方式比如按分存整数或使用专门的高精度方案。8.4 把类型转换想得太随意不是所有值都能安全转换。void main() { int value int.parse(abc); // 会报错 }处理外部输入时优先使用tryParse()。void main() { int? value int.tryParse(abc); print(value); // null }九、总结这一篇我们系统梳理了 Dart 中的数据类型。可以把数据类型理解成数据的容器不同数据需要放进不同容器里容器决定了数据能做什么操作。最常见的基础类型包括num数字类型的父类型。int整数。double小数。bool真假。String文本。dynamic动态类型。集合类型包括List有顺序、可重复。Set不重复。Map键值对。特殊类型包括Function函数也是值。enum固定选项集合。Symbol符号。typedef类型别名。最后类型转换分为隐式转换和显式转换。写 Dart 时不要只看值本身还要关注它的类型。类型选对了后面的代码才会更清晰、更安全、更容易维护。

相关新闻

炉石传说HsMod插件:32倍速加速与200+皮肤定制完全指南

炉石传说HsMod插件:32倍速加速与200+皮肤定制完全指南

炉石传说HsMod插件:32倍速加速与200皮肤定制完全指南 【免费下载链接】HsMod Hearthstone Modification Based on BepInEx 项目地址: https://gitcode.com/GitHub_Trending/hs/HsMod HsMod是一款基于BepInEx框架开发的炉石传说游戏增强插件,为玩家…

2026/10/27 11:37:32 阅读更多 →
Frida动态注入技术:绕过安卓APP抓包检测的三种实战方案

Frida动态注入技术:绕过安卓APP抓包检测的三种实战方案

1. 项目概述:当抓包工具遇上“隐身”的APP搞安卓逆向和渗透测试的朋友,估计都遇到过这种让人头疼的情况:你兴冲冲地打开Burp Suite或者Charles,配置好代理和证书,准备对目标APP来一波流量分析,结果APP一启动…

2026/10/24 11:56:28 阅读更多 →
儿童LLM聊天机器人拟人化交互技术解析与开发实践

儿童LLM聊天机器人拟人化交互技术解析与开发实践

儿童与LLM聊天机器人互动中拟人化现象的技术解析与实践指南 在当今AI技术快速发展的时代,LLM(大语言模型)聊天机器人已经成为儿童教育和娱乐的重要工具。然而,儿童在与这些AI系统互动时表现出的拟人化倾向,即把机器当作…

2026/10/25 7:17:42 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/10/26 12:00:21 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/10/27 4:06:49 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/10/27 7:21:53 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/10/26 12:00:21 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/10/27 6:20:47 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/10/27 4:06:50 阅读更多 →

日新闻

周新闻

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/26 12:00:19 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/27 7:21:50 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/26 8:34:37 阅读更多 →