Dart语言

基础语法

Hello world!

Dart 复制代码
void main(List<String> args) {
  print("hello world");
}

注意:{}后不用加分号

变量与常量的声明

var (当存储数据发生变化,需要用变量var来声明)语法:var 变量名=值/表达式

Dart 复制代码
void main(List<String> args) {
  var age = 20;//第一次赋值以后,类型被确定,后面不允许更改为其他类型
  print(age);
  age = 2;
  print(age);
  var age1 = 20 + 21;
  print(age1);
}
//依次输出20 2 41

const (一开始就是被确定的,且不允许更改,表达式不允许存在变量值) 语法:const=值/表达式

final (场景:当我们需要当前时间作为唯一的操作时间,时间一旦确定就不可以被修改)

语法:final=值/表达式

Dart 复制代码
void main(List<String> args) {
  final time = DateTime.now();//运行时不可被修改,const编译确定,不可修改
  time = DateTime.now();
  print(time);
}
//这么写就会报错

总结const和final:

  • final 是运行时常量(可以在运行时获取值),值在第一次使用时确定。const 是编译时常量(必须在编译时就能推算出结果),值在代码编译时就已经完全确定。
  • 当需要存储一个不变的数据,且编译时就确定,用const(如字符串、数字、固定的配置列表、不变的 UI 组件),但是在运行时才确定,用final(如当前时间、网络请求结果、用户输入、依赖其他变量计算的结果)

常用数据类型

  • 字符串-String

String 属性名='文本内容'; 引号支持单引号或者双引号,支持拼接及模板字符串

Dart 复制代码
void main(List<String> args) {
  String text = "今天是个好日子"; //是个变量 var
  print(text);
  text = "明天也是个好日子";
  print(text);
}
//会打印两行

模板字符串 语法:String 属性名='文本内容变量名'; 或String 变量名 ='文本内容{变量名}';

模板内容是表达式更推荐${}

Dart 复制代码
void main(List<String> args) {
  //我要在当前的时间吃饭
  String content = '我要在${DateTime.now()}吃饭';
  print(content);
}

如果是单独变量,可以直接$变量名

Dart 复制代码
 String a="张三";
 String content="我和$a是好朋友";
  • 数字-int/double/num

int 整数

int 整数 num 可小数可整数 double 小数

Dart 复制代码
void main(List<String> args) {
  int friendcount = 3;
  print("我有$friendcount个朋友");
  double apple = 1.5;
  num rest = 1.3;
  //double 和 int 不能直接赋值 eg:friendcount=apple 是不允许的
  //friendcount = apple.toInt();//但可以转换形式后在赋值,反之也行
  //num也不可直接给double赋值
  //double可直接赋值给num
  rest = apple;//无报错
}
  • Bool类型

列表(List)

场景:当一个变量需要存储多个值的时候,可以用列表类型List

语法:List 属性名='stu1','stu2'

常用操作方法或属性:

  • 在尾部添加-add(内容)
  • 在尾部添加一个列表-addAll(列表)
  • 删除满足内容的第一个-remove(内容)
  • 删除最后一个-removeLast()
  • 删除索引范围内数据 -removeRange(start,end),结束索引不包含在索引范围内,如要删除,再往后推一位。
  • 循环-forEach((item) {});
  • 是否都满足条件-every((item) {return 布尔值}
  • 筛选满足条件的数据-where((item) {return 布尔值})
  • 列表的长度-length
  • 最后一个元素(属性)-last
  • 第一个元素(属性)-first
  • 是否为空(属性)-isEmpty

where 是用来「筛选」的,它会把符合条件的元素挑出来,返回一个新集合。

every 是用来「判断」的,它会检查是否所有元素都符合条件,返回一个 true 或 false。

在使用 every 时,只要遇到第一个不满足条件的元素,它就会立刻返回 false,不会再去检查后面的元素。这在处理大型列表时能节省性能。

Dart 复制代码
//输出hello world
void main(List<String> args) {
  List student = ['张三', '李四', '赵五'];
  student.add('新同学');
  List stu2 = ['A', 'B', 'C'];
  student.addAll(stu2);
  student.forEach((item) {
    print(item); //循环打印
  });
  //是否所有的同学都已新开头
  print(
    student.every((item) {
      return item.toString().startsWith('新');
    }),
  );
  //筛选出以新开头的同学,并转换为一个列表
  student.where((item) {
    return item.toString().startsWith('新');
  }).toList();
  
}

Map

场景:当存储的英文需要找到对应的中文描述,需要使用键值对类型Map

语法1:Map 属性名 ={key :value};

语法2:字典key可以取值和赋值

Dart 复制代码
void main(List<String> args) {
  Map transMap = {"lunch": '午饭', "moring": '早上', "hello": '你好'};
  //通过英文找到对应的中文描述
  print(transMap["lunch"]);
  transMap["hello"] = "你非常好";
  print(transMap["hello"]);
}

Map的常用操作方法

  • 循环-forEach
  • 再添加一个字典-addAll
  • 是否包含某一个key-containsKey
  • 删除某个key-remove
  • 清空-clear
Dart 复制代码
void main(List<String> args) {
  Map transMap = {"lunch": '午饭', "moring": '早上', "hello": '你好'};
  //通过英文找到对应的中文描述
  print(transMap["lunch"]);
  transMap["hello"] = "你非常好";
  print(transMap["hello"]);
  //字典有很多对应对应关系,
  transMap.forEach((key, value) {
    print("$key $value");
  });
  //addAll 给当前字典添加一个字典
  transMap.addAll({"fine": '非常好'});
  print(transMap);
  //containKey判断字典中是否包含某个key
  print(transMap.containsKey("fine"));
  transMap.remove("fine");
  print(transMap);
  //清空字典
  transMap.clear();
  print(transMap);
}

动态类型-dynamic

特点:运行变量运行时自由改变类型,同时绕过编译时的的静态检查。

语法1:dynamic 属性名 =值;

与var 的区别:dynamic运行时可随意改变类型,无编译检查,方法和属性直接调用,var根据初始值进行推断类型,确定类型后类型确定,有编译检查,仅限推断的方法和属性。

空安全机制

定义:通过编译静态检查将运行时的空指针提前暴露

特点:将空指针异常从运行时提前至编译前,减少线上崩溃

Dart 复制代码
void main(List<String> args) {
  String? username = null; //? 表示变量可空
  username?.startsWith("a"); //前面变量有可能为空时,代码不会读后面的属性和方法
  //客观判断
  //sername = "张三";
  //主观判断,开发者一定认为username不为null
  username!.startsWith("a");

  //要保证别人一定显示用户名
  String displayName = username ?? "老高";//如果username有值,显示username,反之显示老高
}

算术运算符

与c语言相同,注意使用整除(~/)时,属性命名不要用double,整除得到的是int类型。

赋值运算符

与c相同

比较运算符

特点:比较运算符得到的结果都是bool类型。其余与c相同。

逻辑运算符

定义:对bool类型进行逻辑运算

&& 逻辑与

|| 逻辑或

! 逻辑非(取反)

流程控制

If分支语句

Dart 复制代码
void main(List<String> args) {
  int source = 61;
  if (source > 60) {
    print("恭喜及格");
  } else if (source > 80) {
    print("恭喜优秀");
  } else {
    print("不及格");
  }
}

三元运算符 语法:表达式(bool值)?结果1:结果2;

switch/case

Dart 复制代码
void main(List<String> args) {
  int state = 1; // 1 待付款 2 待发货 3 待收货
  switch (state) {
    case 1:
      print("待付款");
      break;
    case 2:
      print("待发货");
      break;
    case 3:
      print("待收货");
      break;
    default:
      print("未知");
  }
}

while循环

break跳出整个while循环,continue是跳出当前迭代,进入下一次迭代。

Dart 复制代码
void main(List<String> args) {
  List foods = ["第一个包子", "第二个包子", "第三个包子", "第四个包子", "第五个包子"];
  int index = 0;
  while (index < foods.length) {
    if (index == 2) {
      break;
    }
    print(foods[index]);
    index += 1;
  }
}

for循环

Dart 复制代码
void main(List<String> args) {
  List foods = ["第一个包子", "第二个包子", "第三个包子", "第四个包子", "第五个包子"];
  for (var i = 0; i < foods.length; i++) {
    if (i == 2) {
      continue;
    }
    print(foods[i]);
  }
}

函数

Dart 复制代码
//返回类型 函数名称 参数 函数体
int add(int a, int b) {
  return a + b;
}

分类:

有返回值:具体类型 函数名称(){}

无返回值:void 函数名称 (){}

返回类型可省略,Dart会自动推断类型为dynamic(动态类型,可以为任何类型,不好推断返回值类型)

参数

分为必传参数,可选位置参数,可选命令参数。

特点:

  • 必传参数不为空
  • 可选位置参数必须位于必传参数后面,采用中括号包裹
Dart 复制代码
//合并字符串
String combiong(String a, [String? b, String? c]) {
  return a + (b ?? "默认值b") + (c ?? "默认值c");
}
  • 可选命名参数必须位于必传参数后面,采用大括号包裹
Dart 复制代码
void showPerson(String username, {int? age, String? sex}) {
  print("姓名:$username,年龄:$age,性别:$sex");
}

与可选位置参数可设置默认值

匿名函数

特点:可以生成一个没有名称的函数赋值给变量,进行调用

语法:Function 变量名=(){};

注意:函数类型用Function来声明

Dart 复制代码
void main(List<String> args) {
  oneTest(test);
}

//声明一个匿名函数赋值test变量
Function test = () {
  print("测试数据");
};
//还可以当作参数传递,执行,调用
void oneTest(Function callback) {
  callback();
}

箭头函数

特点:函数体只有一行代码

语法:函数名()=>代码逻辑

注意:可省略return关键字

Dart 复制代码
int add(int a, int b) => a + b;

类(class)

定义:包含属性和方法来定义对象的行为和状态

定义类方法:class Person {属性 方法}

实例化对象:Person 变量=Person();

属性和方法:变量.属性/方法()

Dart 复制代码
class Person {
  String name = "";
  int age = 0;
  String sex = "男";
  void study() {
    print("$name在学习");
  }
}

构造函数

定义:实例化对象的时候,使用构造函数直接给对象中的属性赋值

常见分类:默认构造函数,命名构造函数,构造函数的语法糖

默认构造函数
Dart 复制代码
void main(List<String> args) {
  Person p = Person(name: '老高', age: 12, sex: "男");
  p.study();
}

class Person {
  String? name = "";
  int? age = 0;
  String? sex = "男";
  //默认构造函数
  Person({String? name, int? age, String? sex}) {
    this.name = name;
    this.age = age;
    this.sex = sex;
  }
  void study() {
    print("$name在学习");
  }
}

给类赋值时只需写一行,参数一一对应,提升代码可读性。

命名构造函数

定义:构造函数可以采用命名的方式,返回一个实例化对象

语法:

class 类名{

类名.构造函数名(可选命名参数){}

}

实例化语法:Person p=Person.构造函数名(属性:值)

Dart 复制代码
Person.createPerson({String? name, int? age, String? sex}) {
    this.name = name;
    this.age = age;
    this.sex = sex;
  }
构造函数的语法糖

定义:同名构造函数和命名构造函数都支持简写写法

语法:

class 类名{

类名({this.属性1,this.属性2});

类名.命名函数({this.属性1,this.属性2});

}

Dart 复制代码
Person({this.name, this.age, this.sex});

公有属性和私有属性

共有属性:提供自身或其他外部文件和类使用的属性和方法

私有属性:仅供自身使用的属性和方法,其他外部文件和类无法访问

语法:私有属性以下滑线开头,如_name,其余均为公有属性

继承

定义:拥有父类的属性和方法

特点:dart属于单继承,一个类只能拥有一个直接父类,子类拥有父类所有的属性和方法

语法:class 类名 extends 父类

重写:子类可以通过@override注解重写父类方法,扩展其行为

注意:子类不会继承父类的构造函数,子类必须通过super关键字调用父类构造函数确保父类正确初始化

super语法:子类构造函数(可选命名参数):super({参数})

Dart 复制代码
void main(List<String> args) {
  Child c = Child(name: 'a', age: 1);
  c.study();
}

//父类
class Parent {
  String? name;
  int? age;
  Parent({this.name, this.age});
  void study() {
    print('父类$name在学习');
  }
}

//子类
class Child extends Parent {
  Child({String? name, int? age}) : super(name: name, age: age);
  @override
  void study() {
    //super.study();
    print('子类$name在学习');
  }
}

多态

定义:Dart中的类的是指同一操作作用于不同对象,可以产生不同的执行效果

场景:微信和支付宝都遵循同样的支付接口,但实现逻辑不同。

实现方法:

1.继承和方法重写

Dart 复制代码
void main(List<String> args) {
  PayBase wx = WxPay();
  wx.pay();
}

//父类
class PayBase {
  void pay() {
    print("基础支付");
  }
}

//子类
class WxPay extends PayBase {
  @override
  void pay() {
    print("微信支付");
  }
}

class AliPay extends PayBase {
  @override
  void pay() {
    print("支付宝支付");
  }
}

2.抽象类和接口

方法:使用abstract关键字声明一个抽象类(没有实现体)

使用implements关键字继承并实现抽象类

Dart 复制代码
void main(List<String> args) {
  Paybase wx = WxPay();
  Paybase Ali = AliPay();
  wx.pay();
  Ali.pay();
}

abstract class Paybase {
  void pay(); //抽象类是不写具体实现的
}

//wx支付
class WxPay implements Paybase {
  @override
  void pay() {
    print("微信支付");
  }
}

//支付宝支付
class AliPay implements Paybase {
  @override
  void pay() {
    print("支付宝支付");
  }
}

混入

定义:Dart允许在不使用穿透继承的情况下,向类中添加新的功能

方法:使用mixin关键字定义一个对象

方法:使用with关键字将定义的对象混入到当前的对象

特点:一个类支持with多个mixin,调用优先级遵循"后来居上"原则,即后混入的会覆盖先混入的同名方法

需求(eg):让一个学生类和老师类都拥有唱歌的方法

Dart 复制代码
import 'dart:collection';

void main(List<String> args) {
  Student s = Student(name:"AA");
  s.song(s.name!);
}

//定义一个混入对象
mixin Base {
  void song(String name) {
    print("$name在唱歌");
  }
}

class Student with Base {
  String? name;
  int? age;
  Student({this.name, this.age});
}

class Teacher with Base {
  String? name;
  int? age;
  Teacher({this.name, this.age});
}

泛型

定义:Dart允许使用类型参数,限定类型的同时又让类型更加灵活。

场景(eg):List类型中只想存储String类型怎么办?函数返回值希望和参数一个类型怎么办?

常见分类:泛型集合,泛型方法,泛型类

Dart 复制代码
import 'dart:collection';

void main(List<String> args) {
  //列表泛型 或者Map
  List<String> list = [];
  Map<String, int> map = {};
}

//函数中的方法
T getValue<T>(T value) {
  return value;
}

void printList<T>(List<T> list) {
  for (var i = 0; i < list.length; i++) {
    print(list[i]);
  }
}

class Student<T> {
  T? name;
}

异步编程

Dart是单线程语言,即同时只能做一件事,遇到耗时任务会导致程序阻塞,因此需要异步编程

定义:单线程+事件循环

事件循环:

执行同步代码------>执行微任务队列------>执行实践队列------>结束

微任务队列:Future.microtask()

事件队列:Future,Future.delayed(),I/O操作(文件,网络)等

Future

介绍:代表一个异步操作的最终结果

状态:Uncompleted(等待),Conpleted with a value (成功),Completed with a error(失败)

创建:Future((){})

执行成功:不抛出异常-成功状态-then((){})

执行失败:throw Exception()-失败状态-catchError((){})

Dart 复制代码
void main(List<String> args) {
  Future f = Future(() {
    return "Hello Flutter";
    //没有抛出异常,即为成功状态
    throw Exception();
  });
  //then接受成功状态
  f.then((value) {
    print(value);
  });
  //
  f.catchError((onError) {
    print("出现错误");
  });
}

Future链式调用

介绍:Future可以通过链式的方法连续得到异步的结果

语法:通过Future().then()拿到执行成功的结果

语法:通过Future().catchError()拿到执行失败的结果

注意:在上一个then返回对象会在下一个then中接受

需求:执行三个异步任务,按照顺序排列,最后一次抛出异常

Dart 复制代码
import 'dart:io';

void main(List<String> args) {
  //链式调用
  Future f = Future(() {
    return "Hello Flutter";
  });
  //then接受成功状态
  f
      .then((value) {
        //第一个任务
        return Future(() => "task1");
      })
      .then((value) {
        //第二个任务
        return Future(() => "$value-task2");
      })
      .then((value) {
        //第三个任务
        return Future(() => "$value-task3");
      })
      .then((value) {
        print(value);
        throw Exception("异常");
      })
      .catchError((error) {
        print(error);
      });
}

async/await

介绍:除了then和catchError的方式,还有async和await来实现异步编程

特点:await总是等后面的Future执行成功,才执行下方逻辑,async必须配套await出现

语法:

函数名()async{

try{

await Future();

//Future执行成功才执行的逻辑

}

catch(error){

//执行失败的逻辑

}

}

Dart 复制代码
void main(List<String> args) {
  test();
}

void test() async {
  try {
    String result = await Future(() {
      return "测试";
    });
    print(result);
  } catch (e) {
    print("异步请求出现异常");
  }
}
相关推荐
一只小菜鸡..19 小时前
Stanford CS144 学习笔记 (七):跨越虚实的边界——物理层、链路层与无线网络
网络·笔记·学习
帅次20 小时前
Android 高级工程师面试:Flutter 渲染与性能 近1年高频追问 20 题
android·flutter·面试·渲染·性能
世人万千丶20 小时前
鸿蒙Flutter Icon与IconButton
flutter·华为·harmonyos·鸿蒙
HYDtomako20 小时前
Claude Code学习
学习·ai·agent·claude code
AOwhisky21 小时前
Python 学习笔记(第十一期)——运维自动化(上·后篇):进程级监控与子进程管理——psutil进阶
运维·开发语言·python·学习·云原生·运维开发
程序员老刘21 小时前
跨平台开发地图 | 2026年7月
flutter·ai编程·客户端
凉、介21 小时前
Virtio(三):Virtqueue 建立与 Buffer 提交
笔记·学习·嵌入式·arm·虚拟化·virtio
大模型丫丫21 小时前
Agent开发的难点是什么呢?
大数据·人工智能·学习
世人万千丶1 天前
Flutter 鸿蒙Text组件详解
flutter·华为·harmonyos·鸿蒙·鸿蒙系统