初面网初面网

学习Dart

为什么选择Dart

Dart是一种跨平台的编程语言,由Google开发。它被设计用于构建移动应用、Web应用和服务器端应用

它具有两种模式:JIT模式和AOT模式

在JIT模式下,Dart代码会被编译为字节码,然后在运行时解释执行

在AOT模式下,Dart代码会被编译为本地机器码,直接在目标平台上运行

获取与安装

https://gekorm.com/dart-windows/

vscode中安装code runner和Dart插件

最基本的程序

main(){
  print("hello");
}

判断类型--is

var a = '1';
if(a is String){
  print("yes");
}

变量与常量

// var自动推断类型
var a = 10;
var b = "string";
Null c = null;
String d = "abcd";

// 常量
const e = "err";  // 常量不可修改
final f = "final"; // final是运行时常量,运行时第一次使用才初始化

// 默认值
var de;
de??= "default";
print(de);

// 延迟赋值
late String name;

运算

加、减、乘、除、模、取整

int a = 10;
int b = 3;
int c = 2;

print(a + b);
print(a - b);
print(a * b);
print(a / c);
print(a % b);
print(a ~/ b);  // 取整

字符串

声明

main() {
  String a = 'a';
  String b = "b";
  String c = '''
Hello, World 
''';
  print(a);
  print(b);
  print(c);
}

格式化输出

String a = "hello";
String b = "world";
print("$a $b");

Number型

声明

int a = 10;
double b = 12.5;
print("$a $b");
print(a + b);

List( 数组 / 集合 )

var l1 = ["1",1,1.0,true,[false,]];
print(l1);
print(l1.length);

var l2 = <String>["1"];
print(l2);
l2.add("2");
print(l2);

// 创建定长List,称为集合
// 长度为3,第二个参数是值。默认有类型推导
var l3 = List.filled(2, "12");
// 结果是[12, 12]
var l4 = List<String>.filled(2, "2");

一些属性

属性说明用例
isEmpty是否为空list.isEmpty
reversed翻转list.reversed

一些方法

方法说明用例
add添加list.add(值)
addAll增加多项list.addAll([值,值])
indexOf找到并返回索引。没有则返回-1list.indexOf(值)
remove删除某值list.remove(值)
removeAt删除某个索引的值list.removeAt(索引)
insert某个位置插入值list.insert(索引,值)
insertAll批量插入list.insertAll(索引,值)
join转为字符串。带参的话会添加分隔符list.join('-')
toList其他类型转为listotherType.toList()
fillRange范围内改值。左闭右开list.fillRange(始,终,值)

遍历数组

const list = [1,2,3,4,5];

for(var i in list){
  print(i);
}

list.forEach((element) {
  print(element);
});

处理并返回为map

const list = [1,2,2,2,5];
var m = list.map((value){
  return value+1;
})
print(m);

去重

const list = [1, 2, 2, 2, 5];
var s = new Set();
s.addAll(list);
print(s.toList());

过滤

const list = [1, 2, 3, 4, 5];
var newList = list.where((element) => element > 2);
// 如果不是一行写的要这种形式
// var newList = list.where((element) {
//   return element > 2;
// });
print(newList.toList());

Set

无重复数据的数组

// 声明
var s = new Set();

Map

var person = {
  "name": "Tom",
  "age": 20
};
print(person);
print(person['name']);
person["home"] = "good";  // 添加项
print(person);

var cat = new Map();

cat['name'] = 'Mimi';
print(cat);

一些属性

属性说明用例
keysmap.keys.toList()
valuesmap.values
isEmpty是否为空map.isEmpty

一些方法

方法说明用例
addAll批量增加值map.addAll({键:值})
remove按键删除map.remove(键)
containsValue查找是否有某个值map.containsValue(值)
containsKey查找是否有某个键。返回布尔值map.containsKey(键)

判断

if

int a = 1;
String b = '1';
if(a == b){
  print("yes");
} else{
  print("no");
}

switch

String name = "Tom";
switch(name){
  case 'John':
    print('Hello, $name');
    break;
  case 'Tom':
    print('Hello, $name');
    break;
  default:
    break;
}

三目运算符

bool flag = false;
String a = flag ? 'true' : 'false';
print(a);

循环

for

for(int a = 10;a>0;a--){
  print(a);
}

while

int a = 10;
while(a>0){
  a--;
};

do...while

int a = 10;
do{
  print(a);
  a--;
}while(a>0);

类型转换

var intStr = int.parse('123');
var doubleStr = double.parse('123.66');

print(intStr);
print(doubleStr);

判断字符串是否空,是否为无法计算的数字NaN

String a = '';
print(a.isEmpty);
int b = 0/0;
print(b.isNaN);

函数

返回值类型 方法名(参数1,参数2,...){
  方法体
  return 返回值;
}

// 返回值类型可以省略
void addNum(int a, int b){
  return a+b;
}

// 可选参数
// 类型后面的问号,代表变量为可空类型
void addNum(int a, int b, [int? c]){
  if(c != null){
    return a+b+c;
  }else{
    return a+b;
  }
}

// 命名参数(必传参数)
mustParamsFunc(int a, {require int b, String c='Tom'}){}

闭包

方法A里面有方法B,并且方法A返回了方法B。

func1() {
  var a = 10;
  return () {
    a++;
    print(a);
  };
}

var b = func1();
b();
b();
b();

所有东西都是对象,所有对象都继承自Object类。

所有对象都是类的实例,所有类都是Object的子类。

类,通常由属性和方法组成。

main() {
  Human human = new Human();

  human.setName('老王');
  human.getName();

  var r = new Human.reset();
}

// 首字母大写
class Human {
  // 属性
  late String name;
  late int age;

  // 构造方法
  Human(String name, int age){
    this.name = name;
    this.age = age;
  }

  // 构造函数简写
  // Human(this.name, this.age);

  // 命名构造函数。命名构造函数可以有多个
  Human.reset(){
    print('reset');
  }

  // 方法
  void getName() {
    print(this.name);
  }

  void setName(String name) {
    this.name = name;
  }
}

连缀

class Rect{
  late int width;
  late int height;

  void printArea(){
    print(width * height);
  }
}

main(){
  Rect r = new Rect();
  r..width = 10
    ..height = 10
    ..printArea();
}

抽离为单独文件

// demo01.dart
class Human {
  // 属性
  late String name;
  late int age;
  //late int _age;  单独文件中下划线开头意味着这是私有的

  Human(this.name, this.age);
}

// demo02.dart
// 同级不用./,文件夹同理
import 'demo01.dart';

main() {
  Human human = new Human('Tom', 18);
  print(human.name);
  print(human.age);
}

属性方式访问方法

// demo02.dart
class Rect{
  late double _width;
  late double _height;
  Rect(this._width, this._height);
  get area{
    return this._width * this._height;
  }
}

// demo01.dart
import 'demo02.dart';

main() {
  Rect rect = new Rect(10, 23);
  print(rect.area);
}

构造函数默认带参

class Rect {
  late double _width;
  late double _height;
  Rect()
      : _width = 2,
        _height = 4;
  get Area {
    return this._width * this._height;
  }
}

main() {
  Rect rect = new Rect();
  print(rect.Area);
}

静态属性、静态方法

静态方法只能访问静态属性

静态成员不用实例化就能访问

class Rect {
  static late int width;
  late int height;

  static void getWidth() {
    print(width);
  }

  static void setWidth() {
    width = 10;
  }

  void printAll() {
    print(width);
    print(this.height);
  }
}

main() {
  Rect.setWidth();
  Rect r = new Rect();
  r.printAll();
  print(Rect.width);
}

继承

用extends来继承

继承父类里可见的属性和方法,不会继承构造函数

复写父类的方法 getter setter

普通类只有单继承

class Father{
  String name = 'F';
  void printName()=>print(this.name);
  void fatherFunc()=>print('func');

  Father(String name){
    this.name = name;
  }
}

class Child extends Father{
  // super将构造接收的变量传到父类中的构造
  Child(String name):super(name){
    super.fatherFunc();
  }

  String name = 'C';

  // 覆写
  @override
  void printName()=>print(this.name);
}
main() {
  Child c = new Child('Child');
  c.printName();
}

抽象类

抽象类里不需要写出方法体的叫抽象方法。写出方法体的方法,会成为普通方法。

抽象类用于规定子类必须完成的方法。子类必须重写抽象类中给出的所有抽象方法。

抽象类不能被实例化。

abstract class Animal{
  eat();
}

class Dog extends Animal{
  @override
  void eat(){
    print('dog eat');
  }
}

接口

接口用implement定义。尽管普通类和抽象类都可以成为接口,但是为了程序健壮性,推荐使用抽象类作为接口的定义。

dart中的接口要求内部方法全部被重写。这也是推荐以抽象类作为接口的原因之一。

一个类可以有多接口,类中间由逗号分隔

abstract class Animal{
  late String name;
  eat();
}

class Dog implements Animal{
  @override
  late String name;
  @override
  eat()=>print('dog eat');
}

main(){
  Dog d = new Dog();
  d.eat();
}

mixin

类似于继承,但是只能继承Object类的直系类。

作为mixin的类,不能有构造函数。

注意,mixin不是继承,也不是接口。形式上像,但本质上不是。

同名函数,后覆盖前

class A{}
class B{}
class C with A,B{}

这样,C会继承A,B中所有可继承的属性和方法。

泛型

T getData<T>(T v){
  return v;
}

main(){
  print(getData<int>(5));
}

泛型类

class NameClass<T> {
  NameClass(T value) {
    print(value);
  }
}

main() {
  NameClass nc = new NameClass(1);
}

identical

两个引用是否指向同一个对象。

bool identical(Object? a, Object? b);

每个dart文件都是一个库。library指令可以新建库。

  • 内置库

dart

, dart
, dart

  • pub包管理系统中的库

https://pub.dev/packages

  1. 项目根目录新建pubspec.yaml
  2. 配置名称、描述、依赖等信息
  3. 运行pub get获取包下载到本地
  4. 引入库import 'package
    /http.dart' as http;
  • 别名

import 'xxx' as xxx;

异步执行

async/await

void main() async {
  var result = await getRemote();
}

更新于 2025/11/3