一文快速学会 dart
前言
本篇是本人学习dart 的学习笔记,由于本人有其他语言的基础,所以有些地方不会写的很细。
这里是看这个教程,还是比较推荐的。
黑马程序员Flutter从入门到实战全套视频教程,从Dart语言到Flutter核心框架AI辅助开发,一套搞定Android、iOS、HarmonyOS及Web
flutter 安装
https://docs.flutter.cn/community/china/
1、下载flutter
flutter 安装还非常简单的,你只需要下载下来,然后解压缩,再配置一下环境变量就行了。
下载之后,进行解压缩即可。
2、配置环境变量
打开 设置
在设置中搜索环境变量,找到编辑环境变量
需要添加两个环境变量
PUB_HOSTED_URL=https://mirrors.tuna.tsinghua.edu.cn/dart-pub
FLUTTER_STORAGE_BASE_URL=https://mirrors.tuna.tsinghua.edu.cn/flutter
只需要在这里写上变量名就行了。
为什么我们要在dart教程里面,安装flutter呢?
1.flutter里面自带dart
2.dart现在最常用的就是flutter框架了,顺便安装一下。
变量
dart 的 变量跟其他的区别不是很大,主要记住以下几点
var //声明变量,dart会自己推断类型,很方便,就像在用python,js等
final // 声明运行时常量
const // 声明编译时常量
类型名 //使用 int等来声明变量
var
使用var 声明变量的时候需要注意,
变量声明之后,变量的类型不能改变。
void main(){
var a = 1;
a = a.toString();
print(a);
}
可以试一下这个,会报错,但是python不会
const
是用const声明变量的时候,需要注意
const 是编译时常量,在编译的时候,就确定的常量
const中不能有变量,不能使用表达式
void main(){
var a = 1;
const b = a*2;
print(b);
}
可以试一下这个
final
final 是运行时常量,比如,文章发表的时间是固定的,并且你也不想让他修改,就可以使用final ,并且final 还可以使用表达式。
void main(){
var a = 1;
final b = a*2;
print(b);
}
可以试一下这个,可以就能正常运行。
变量类型
dart 的变量类型,跟其他语言没有太多的差别
dart 的类型还是分为,值类型,集合类型和特殊用途类型
特殊用途类型可以自己google 一下,比如 symbol,type等,我觉得暂时这里就不说了,一般这种都属于进阶内容,也不常用。
值类型
值类型分为 数值类型,字符串类型和布尔类型
数值类型分为 int类型和double类型,也就是整数类型和浮点数类型,
在dart里面还有一个num类型,既可以声明int,也可以声明double。
下面说一下值类型常用的操作,这在其他语言里面也常用的。
算术运算
int a = 5;
int b = 2;
a + b; // 7
a - b; // 3
a * b; // 10
a / b; // 2.5 永远是 double
a ~/ b; // 2 整除(向下取整)
a % b; // 1
a += 1;
a -= 2;
a *= 3;
a ~/= 2;
a++;
++a;
学会这些代码,就相当于掌握编程里面的运算了
但是我这里要说一下在写代码时候的原则,写代码,永远是怎么简单,少歧义,怎么来。在编写业务代码的时候,永远都是看一眼就知道写的是什么的代码才是好代码。
++a这种写法是语法能运行的,但是尽量不要写
原因是,容易给自己,给其他人挖坑。
运算优先级
我们在上学的时候,都学过,先算乘除,再算加减。这里我不教你复杂的规则,这里我只教你一句话
括号的优先级是最高的,编程语言永远都是先计算括号里面,再一步一步向外面计算。遇到拿不定主意的,请一定要使用括号!!!
类型转换
类型转换就是把int类型转成double 类型,把double类型转成int类型,
后面我们还会学习字符串类型,也能进行相互转换。
int a = 10;
double d = a.toDouble();
int b = d.toInt(); // 截断
int c = d.round(); // 四舍五入
int e = d.floor(); // 向下取整
int f = d.ceil(); // 向上取整
数学函数
在我们开发的时候,经常会需要用到一些数学处理,比如最大值,最小值,指数函数,等等吧。
你可以自己实现,也可以使用标准库。
注意:
不要成为只会调包的人,在调包的时候,多想一想怎么实现的。
比如max怎么实现?
min怎么实现?
如果你是看我的博文看到这里,并且还没有编程基础,这个一个超纲题,需要你要有后面的知识。
import 'dart:math';
void main(){
int a = 10;
int b = 20;
print(max(a, b));
print(min(a, b));
print(sqrt(16));
print(pow(2, 3)); // 8
}
模版字符串
模版字符串,简单来说就是,你想在字符串中间带上一点变量,当这个变量出现不同的值,打印出来的东西也不一样。
语法很简单
'hello $name'
'age=${age + 1}'
'len=${list.length}'
就这两种情况,我比较推荐使用表达式的方式,比较万能,不容易踩坑。
字符串类型转换
int.tryParse('123') ?? 0;
double.tryParse('3.14') ?? 0.0;
123.toString();
3.14159.toStringAsFixed(2); // 3.14
字符串常用操作
我们日后会进行跟字符串打交道,会有各种各样的需要
我这里不一定能写全
查询字符串的基本信息
String s = 'hello world';
s.length; // 长度
s.isEmpty; // 是否为空
s.isNotEmpty; // 是否非空
字符串拼接
var name = 'Tom';
var age = 18;
'hello $name';
'age=${age + 1}';
var buf = StringBuffer();
buf.write('a');
buf.write('b');
var s = buf.toString();
查找
s.contains('world');
s.startsWith('hello');
s.endsWith('ld');
s.indexOf('o'); // 找不到返回 -1
s.lastIndexOf('o');
截取
s.substring(0, 5); // hello
替换
s.replaceAll('o', '0');
s.replaceFirst('o', '0');
分割
'a,b,c'.split(','); // ['a', 'b', 'c']
合并
['a', 'b', 'c'].join('-'); // a-b-c
大小写&去掉空格
s.toUpperCase();
s.toLowerCase();
' hi '.trim();
' hi'.trimLeft();
'hi '.trimRight();
正则表达式
正则表达式是一种用于匹配和操作文本的强大工具,它是由一系列字符和特殊字符组成的模式,用于描述要匹配的文本模式。
正则表达式可以在文本中查找、替换、提取和验证特定的模式。
这个,只要会用就行了,能用大模型写正则表达式就行了,正则表达式非常抽象,人肉写的话,学习成本非常高,所以这里我一般都是使用大模型来写。
多行字符串
var s = '''
line1
line2
line3
''';
驼峰命名法和下划线命名法
这个东西非常重要,算是约定俗成的东西
驼峰命名法,分为大驼峰命名法和小驼峰命名法
说人话就是,英文单词的首字母是否大写
大小驼峰命名法的区别是,变量的首字母是否大写
isWorkFinished //小驼峰命名法
IsWorkFinished //大驼峰命名法
下划线命名法又叫蛇形命名法,snake_case,简单来说就是,在字符串之间用下划线进行分割。
metric_processor //下划线命名法
不同语言对于变量,文件名,都有不同的约定,dart大概如下。
变量小驼峰,类名大驼峰
私有加下划线,文件用下划线
bool 要有 is,集合要复数
命名法尽量遵守,这样写出来的代码更好看一点,别人也能看得懂。
这里我写一点反例
// 单字母乱飞
var a = 10;
var b = 'hello';
var c = true;
//使用拼音
var shijian = DateTime.now();
var yonghuId = 123;
// 滥用缩写
var cfg = loadCfg();
var usrMgr = UserMgr();
变量命名总的来说,就是要清晰明了,让你看到你这个变量是在干啥
// 工作是否完成
isWorkFinished
//超时时间
timeout
布尔类型
bool类型就是 true 和 false ,表示这个是真的,还是假的。
布尔类型最常用的就是进行比较运算,这个会非常常用,后面基本是要靠bool类型来驱动的。
数值类型是可以比较,string类型也是可以比较的。string上面也写了,包不包含。
a > b;
a < b;
a >= b;
a <= b;
a == b;
a != b;
容器类型
容器类型,是一类数据结构,为了方便我们对数据进行处理,
在英文里面,我们一般叫 Collection。
容器本身没有好坏之分,只有适不适合当前场景。
在学习容器时,请牢记四字箴言:
增 · 删 · 改 · 查
在 Dart 语言中,内置且最常用的容器主要有三种:
- List:有序集合
- Set:无序去重集合
- Map:键值对集合
下面我们逐一来看。
List(列表)
List 是 Dart 中使用频率最高的容器,用来存放一组有顺序、可重复的数据。
1. List 的声明
List<int> numbers = [1, 2, 3];
var names = ['Tom', 'Jack'];
推荐显式声明类型,避免 List<dynamic> 带来的隐性问题。
// 不推荐
var list = [];
// 推荐
List<String> list = [];
2. 增(Add)
numbers.add(4); // 在末尾追加
numbers.insert(0, 100); // 在指定位置插入
numbers.addAll([5, 6]); // 批量添加
3. 删(Delete)
numbers.remove(2); // 删除指定值(只删第一个)
numbers.removeAt(0); // 根据下标删除
numbers.removeLast(); // 删除最后一个
numbers.clear(); // 清空列表
注意:删除一个不存在的元素 不会报错。
4. 改(Update)
numbers[0] = 999;
List 是通过下标修改的,这是它和 Set 的本质区别之一。
5. 查(Query)
numbers[0]; // 根据下标访问
numbers.contains(3); // 是否包含某个元素
numbers.indexOf(3); // 返回下标,不存在返回 -1
numbers.length; // 元素个数
numbers.isEmpty; // 是否为空
条件查询:
var result = numbers.where((e) => e > 2).toList();
6. 常见坑
- 遍历过程中删除元素会抛异常
// 错误示例
for (var e in numbers) {
if (e == 2) numbers.remove(e);
}
正确写法:
numbers.removeWhere((e) => e == 2);
Set(集合)
Set 用于存放不重复的数据,常见于去重、存在性判断等场景。
1. Set 的声明
Set<int> ids = {1, 2, 3};
注意:
var s = {}; // 这是 Map,不是 Set
var s = <int>{}; // 才是 Set
2. 增 / 删 / 查
ids.add(4);
ids.remove(2);
ids.contains(3);
ids.length;
Set 没有下标,因此不存在真正意义上的“改”,只能通过删除后再添加实现。
Map(映射)
Map 用于表示 键值对(Key → Value) 关系,是第二常用的容器。
1. Map 的声明
Map<String, int> scores = {
'Tom': 90,
'Jack': 80,
};
2. 增 / 改
scores['Lucy'] = 95; // 新增
scores['Tom'] = 100; // 修改(key 已存在)
3. 删
scores.remove('Jack');
scores.clear();
4. 查(重点)
scores['Tom']; // key 不存在时返回 null
scores.containsKey('Tom');
scores.containsValue(90);
scores.keys;
scores.values;
建议在访问前判断 key 是否存在,避免空值问题。
–
动态类型(dynamic / Object)
Dart 是一门 强类型 + 类型推断 的语言,但它也支持动态类型,用于一些灵活或过渡场景。
dynamic
var a = 1; // 推断为 int
dynamic b = 1; // 动态类型
b = 'hello'; // 合法
b = true; // 合法
dynamic 会关闭编译期类型检查,不推荐大量使用,否则容易把 Dart 写成 JS。
Object
Object obj = 'hello';
obj = 123;
Object 是所有类型的父类,但 不能直接调用子类方法,比 dynamic 更安全。
原则:
能不用 dynamic 就不用
宁愿写明确类型,也不要图省事
空安全(Null Safety)
Dart 从 2.12 开始引入了空安全,这是一个非常重要的特性。
- 可空类型和非空类型
String name = 'Tom';
String? nickName;
String:不能为 null
String?:可以为 null
- 空值访问
nickName?.length; // 安全访问
等价于:
if (nickName != null) {
nickName.length;
}
3. 空值兜底(??)
String displayName = nickName ?? ‘匿名用户’;
4. 强制非空(!)
print(nickName!.length);
⚠️ 如果此时为 null,会直接运行时崩溃,谨慎使用。
条件控制
if / else
if (score >= 90) {
print('优秀');
} else if (score >= 60) {
print('及格');
} else {
print('不及格');
}
条件必须是 bool,不能像 JS 那样随便写。
switch / case
switch (status) {
case 0:
print('初始化');
break;
case 1:
print('进行中');
break;
default:
print('未知状态');
}
注意:
每个 case 必须 break
支持 int / String / enum
循环
for 循环
for (int i = 0; i < 3; i++) {
print(i);
}
for-in(遍历集合)
for (var item in list) {
print(item);
}
⚠️ 遍历 List 时不要删除元素。
while / do-while
while (count > 0) {
count--;
}
do {
print('至少执行一次');
} while (false);
break / continue
for (var i = 0; i < 10; i++) {
if (i == 3) continue;
if (i == 7) break;
}
函数
函数定义
int add(int a, int b) {
return a + b;
}
简写函数(箭头函数)
int add(int a, int b) => a + b;
可选参数
void log(String msg, {String level = 'INFO'}) {
print('[$level] $msg');
}
log('hello');
log('error', level: 'ERROR');
可空参数
void printName(String? name) {
print(name ?? '匿名');
}
更多推荐
所有评论(0)