百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 热门文章 > 正文

Dart简易入门基础 dart教程

bigegpt 2024-10-15 08:38 23 浏览

变量类型

// 通过 var 定义的变量会自动推导变量类型
var text = 'Hello world';

字符串

String str = '你好 dart';

Number 类型

int

整数值;长度不超过 64位

int num = 123456;

double

64位的双精度浮点数字

int x = 1.252256;

布尔

bool isBool = true;
print(isBool);

// 不允许使用 if(value) 或者 assert(value) 的方式来检查布尔值
//var fullName = '';
//if (fullName) {
//  print(111);
//}

// 检查是否为空字符串 .
var fullName = '';
assert(fullName.isEmpty);

// 检查是否小于等于零。
var hitPoints = 0;
assert(hitPoints <= 0);

// 检查是否为 null。
var unicorn;
assert(unicorn == null);

// 检查是否为 NaN。
var iMeantToDoThis = 0 / 0;
assert(iMeantToDoThis.isNaN);数组 集合类型

数组 集合类型

// 类型推导
var list1 = [1, 2, 3];

// 字面量
var list2 = [];
list2.add('张三');
list2.add('李四');
list2.add('王五');

// 定义 List 指定类型
var list3 = <String>[];
list3.add('张三');

Map(对象)

// 字面量
var person = {
  "name":"张三",
  "age":20
};

// 使用构造器  这里的 new 关键词可以省略
var gifts = new Map();
gifts['first'] = 'partridge';
gifts['second'] = 'turtledoves';
gifts['fifth'] = 'golden rings';

Final 和 Const

一个 final 变量只可以被赋值一次;一个 const 变量是一个编译时常量(const 变量同时也是 final 的)。顶层的 final 变量或者类的 final 变量在其第一次使用的时候被初始化。


final name = 'Bob';
final String nickname = 'Bobby';
var foo = const [];
final bar = const [];
const baz = []; // 相当于 `const []` (Equivalent to `const []`)

运算符

算术运算符

int a = 18;
int b = 5;

print(a - b); // 减
print(a + b); // 加
print(a * b); // 乘
print(a / b); // 除
print(a % b); // 取余
print(a ~/ b); // 取整

自增自减操作

var a, b;

a = 0;
b = ++a; // 在 b 赋值前将 a 增加 1。
assert(a == b); // 1 == 1

a = 0;
b = a++; // 在 b 赋值后将 a 增加 1。
assert(a != b); // 1 != 0

a = 0;
b = --a; // 在 b 赋值前将 a 减少 1。
assert(a == b); // -1 == -1

a = 0;
b = a--; // 在 b 赋值后将 a 减少 1。
assert(a != b); // -1 != 0

关系运算符

int a = 5;
int b = 3;

print(a == b);
print(a != b);
print(a > b);
print(a < b);
print(a >= b);
print(a <= b);

逻辑运算符


// 取反
bool flag = false;
print(!flag);

// && 并且:全部为true的话值为true,否则为false
bool a = true;
bool b = false;
print(a && b);

// || 或与:全部为false的话值为false,否则为true
bool c = false;
bool d = false;
print(c || d);

类型判断运算符

is 如果对象是指定类型则返回 true


var str = '123';
if (str is String) {
  print('String 类型');
} else if (str is int) {
  print('int 类型');
}

is! 如果对象是指定类型则返回 false

var str = '123';
if(str is! String){
  print('String 类型');
}

赋值运算符

??=

如果b为空,就把23赋值给b

var b;
b ??= 23;

条件表达式

三目运算

// 根据布尔表达式
bool isPublic = true;
var visibility = isPublic ? 'public' : 'private';

// 根据判定是否为 null
String playerName(String name) => name ?? 'Guest';

级联运算符

级联运算符(..)可以让你在同一个对象上连续调用多个对象的变量或方法。


// 数组集合的级联
List<int> listInt = []
    ..add(0)
    ..add(1)
    ..add(2)
    ..removeAt(1);
  print(listInt); // output: [0, 2]

// 对象字典的级联
Map<String,dynamic> aMap = Map()
    ..putIfAbsent('name', ()=>'bill')
    ..putIfAbsent('name', ()=>'gate')
    ..addAll({'sex':'male', 'age':1})
    ..remove('age');
  print(aMap); // output: {name: bill, sex: male}

类型转换

String 转 Number


String str = '123';
var num = int.parse(str);
print(num is int);

var num2 = double.parse(str);
print(num2 is int);

// double 可以转 int,但是 int 不能转换 double 类型数字。值为空时报错

Number 转 String

var number = 12;
var str = number.toString();
print(str is String);

其它类型转换成Boolean类型

// 字符串转布尔
var str = '123';
if (str.isEmpty) {
  print('str 为空');
} else {
  print('str 不为空');
}
// 数字转布尔
var num = 123;
if (num == 0) {
  print(0);
} else {
  print('非0');
}

集合类型 List Set Map

List

常用属性和方法

常用属性:

  • length 长度
  • reversed 翻转
  • isEmpty 是否为空
  • isNotEmpty 是否不为空

List list = ['香蕉', '苹果', '西瓜', '梨子', '草莓'];

print(list.length);       // 5
print(list.isEmpty);      // false
print(list.isNotEmpty);   // true
print(list.reversed.toList());

常用方法:

  • add 增加
  • addAll 拼接数组
  • indexOf 查找 传入具体值,返回索引,查找不到返回-1
  • remove 删除 传入具体值
  • removeAt 删除 传入索引值
  • fillRange 修改
  • insert(index,value) 指定位置插入
  • insertAll(index,list) 指定位置插入List
  • toList() 其它类型转换成List
  • join() List转换成字符串
  • split() 字符串转换成List
  • forEach
  • map
  • where
  • any
  • every

List list = ['香蕉', '苹果', '西瓜', '梨子', '草莓'];

list.add('地瓜');
print(list);

list.addAll(['桃子', '葡萄']);
print(list);

print(list.indexOf('梨子'));

list.remove('葡萄');
print(list);

list.removeAt(2);
print(list);

list.fillRange(1, 2, '柿子');
print(list);

list.insert(1, '');
print(list);

list.insertAll(1, ['', '']);
print(list);

var str = list.join(',');
print(str);

list = str.split(',');
print(list);

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

for (var i = 0; i < list.length; i++) {
  print(list[i]);
}

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

List list = [1, 2, 3, 4, 5, 6, 7];

// 遍历集合,返回新的集合
var newList = list.map((value) {
  return value * 2;
});
print(newList);

// 返回满足条件的集合
var newList = list.where((value) {
  return value > 5;
});
print(newList.toList());

// 只要满足条件的就返回true
var f = list.any((value) {
  return value > 5;
});
print(f);  // true

// 每一个都要满足条件才返回true,否则false
var f = list.every((value) {
  return value > 5;
});
print(f);

Set

定义集合


var s = new Set();
s.add('香蕉');
s.add('苹果');
s.add('苹果');

print(s); // {香蕉, 苹果}  集合去重

print(s.toList());

List list = ['香蕉', '苹果', '西瓜', '梨子', '草莓', '西瓜', '苹果'];
var s = new Set();
s.addAll(list);
print(s);
print(s.toList());

List list = ['香蕉', '苹果', '西瓜', '梨子', '草莓', '西瓜', '苹果'];
var s = new Set();
s.addAll(list);

s.forEach((element) => print(element));

Map

常用属性和方法

常用属性:

  • keys 获取所有的key值
  • values 获取所有的value值
  • isEmpty 是否为空
  • isNotEmpty 是否不为空

常用方法:

  • remove(key) 删除指定key的数据
  • addAll({…}) 合并映射 给映射内增加属性
  • containsValue 查看映射内的值,返回true/false
  • map

定义


Map person = {'name': '张三', 'age': 20};

Map student = new Map();
student['name'] = '李四';

Map person = {'name': '张三', 'age': 20};

print(person.keys.toList());
print(person.values.toList());
print(person.isEmpty);
print(person.isNotEmpty);

Map person = {'name': '张三', 'age': 20, 'sex': '男'};

person.addAll({
  'work': ['前端工程师', '安卓工程师'],
  'height': 168
});

person.remove('sex');

print(person.containsKey('张三'));

print(person.containsValue('张三'));

print(person);

Map person = {'name': '张三', 'age': 20, 'sex': '男'};

person.forEach((key, value) {
  print("$key ---- $value");
});

函数

定义函数

返回类型 方法名称(参数1,参数2,...){
  方法体
  return 返回值;
}
void main() {
  printInfo();
  print(getNum());
  print(printUserInfo());
  print(getList());
}

void printInfo() {
  print('自定义方法');
}

int getNum() {
  return 123;
}

String printUserInfo() {
  return '用户名';
}

List getList() {
  return [1, 2, 3];
}

简写

如果函数体内只包含一个表达式,你可以使用简写语法

bool isBool(int num) => num > 1

函数参数

函数可以有两种形式的参数:必要参数 和 可选参数。必要参数定义在参数列表前面,可选参数则定义在必要参数后面。可选参数可以是 命名的 或 位置的。

必要参数

String printUserInfo(String username, int age) { // 形参
  return "姓名:$username---年龄:$age";
}
print(printUserInfo('张三', 18)); // 实参

可选参数

String printUserInfo(String username, [int? age]) {
  if (age != null) {
    return "姓名:$username---年龄:$age";
  }
  return "姓名:$username---年龄:保密";
}

默认参数

String printUserInfo(String username, [int? age, String sex = "男"]) {
  if (age != null) {
    return "姓名:$username---性别:$sex---- 年龄:$age";
  }
  return "姓名:$username---性别:$sex---年龄:保密";
}

命名参数

String printUserInfo(String username, {int? age, String sex = "男"}) {
  if (age != null) {
    return "姓名:$username---性别:$sex---- 年龄:$age";
  }
  return "姓名:$username---性别:$sex---年龄:保密";
}
printUserInfo('张三', age: 20)

将函数作为参数传递给另一个函数

void fn1() {
  print('fn1');
}

void fn2(fn) {
  fn();
}

fn2(fn1);

箭头函数

List list = [1, 2, 3, 4, 5];
list.forEach((element) => print(element));
list.forEach((element) => {
  print(element)
});
var newList = list.map((e) => e > 2 ? e * 2 : e);
print(newList.toList());

匿名函数

var printNum = (int num) {
  print(num);
};
printNum(123);

自执行函数

((n) {
    print('自执行函数 $n');
  })(1);

闭包函数

全局变量常驻内存,全局变量污染全局。
局部变量不常驻会被垃圾机制回收,不会污染全局

函数嵌套函数,内部函数会调用外部函数的变量或参数.并reutrn里面的函数

Function makeAdder(int addBy) {
  return (int i) => addBy + i;
}
var add2 = makeAdder(2);
print(add2(2));

创建类

class Person {
  String name = '张三';
  int age = 28;

  void getInfo() {
    print("$name --- $age");
    print("${this.name} --- ${this.age}");
  }
}
Person p1 = new Person();
print(p1.name);
p1.getInfo();

构造函数

如果你没有声明构造函数,那么 Dart 会自动生成一个无参数的构造函数并且该构造函数会调用其父类的无参数构造方法。子类不会继承父类的构造函数,如果子类没有声明构造函数,那么只会有一个默认无参数的构造函数。

默认构造函数
声明一个与类名一样的函数即可声明一个构造函数

class Person {
  String name;
  int age;

  // 默认构造函数,实例化时触发
  Person(this.name, this.age);

  void printInfo() {
    print("${this.name} --- ${this.age}");
  }
}
Person p1 = new Person('张三', 20);

命名式构造函数

可以为一个类声明多个命名式构造函数来表达更明确的意图。

class Point {
  double x, y;

  Point(this.x, this.y);

  // 命名式构造函数
  Point.origin()
      : x = 0,
        y = 0;
}
Point.origin()

私有属性和方法

通过给属性和方法加上下划线 _,将属性和方法变成私有的。

class Animal {
  String _name;
  int age;

  Animal(this._name, this.age);

  String getName() {
    return this._name;
  }

  void _run() {
    print('私有方法');
  }

  execRun() {
    // 类里面的方法互相调用
    this._run();
  }
}

getter 和 setter

class Rect {
  num height;
  num width;

  Rect(this.height, this.width);

  get area {
    return this.width * this.height;
  }

  set areaHeight(value) {
    this.height = value;
  }
}

Rect a = new Rect(10, 4);
print(a.area);
a.areaHeight = 50;
print(a.height);

初始化列表

class Person {
  String name;
  int age;

  //在构造函数执行之前进行初始化变量
  Person(): name = '张三',age = 26;

  void printInfo() {
    print("${this.name} --- ${this.age}");
  }
}

静态成员

  1. 使用static关键字来实现类级别的变量和函数
  2. 静态方法不能访问非静态成员,非静态方法可以访问静态成员
class Person {
  static String name = '张三';
  int age = 20;

  static void show() {
    print(name);
  }

  void printInfo() {
    print(name);  // 访问静态属性

    print(this.age); // 访问非静态属性

    show();   // 调用静态方法
  }
}
Person.show();
Person().printInfo();

对象操作符

  • ? 条件运算符
  • as 类型转换
  • is 类型判断
  • .. 级联操作
class Person {
  String name;
  int age;

  Person(this.name, this.age);

  void printInfo() {
    print(this.name);
    print(this.age);
  }
}
Person p = new Person('张三', 18);
if (p is Person) {
  p.name = '李四';
}
p.printInfo();

var p1;
p1 = '';
p1 = new Person('张三', 18);
(p1 as Person).printInfo();
p1.printInfo();


Person p2 = Person('占山', 20);
p2
  ..name = '张三'
  ..age = 56
  ..printInfo();

继承

  1. 子类使用extends关键词来继承父类
  2. 子类会继承父类里面可见的属性和方法,但是不会继承构造函数,和静态方法
  3. 子类会覆写父类的方法 getter和setter
void main() {
  Student s = Student('张三', 15, '男');

  // 子类继承父类的属性和方法
  s.printInfo();
  s
    ..name = '李四'
    ..age = 18
    ..printInfo();

  s.eat();

  s.say();
}

class Person {
  String name;
  int age;

  Person(this.name, this.age);

  Person.birth(this.name, this.age);

  void printInfo() {
    print(this.name);
    print(this.age);
  }

  say() {
    print("${this.name} --- ${this.age}");
  }

  static void teaching() {
    print('父类静态方法');
  }

  void eat() {
    print('Person类的eat方法');
  }
}

class Student extends Person {
  String? sex; // 如果字段或变量不能在声明中初始化,但总是在引用之前初始化,则将其标记为延迟

  // : super 初始化列表 给父类构造函数传参
  Student(String name, int age, String sex) : super(name, age) {
    this.sex = sex;
  }

  // 命名构造函数传参
  // Student(String name, int age, String sex) : super.birth(name, age) {
  //   this.sex = sex;
  // }

  @override
  say() {
    print("${this.name} --- ${this.age} --- ${this.sex}");
  }

  // 覆写父类的方法
  @override
  void eat() {
    print('Student类的eat方法');
  }
}

抽象类

抽象类主要用于定义标准,子类可以继承抽象类,也可以实现抽象类接口

  1. 抽象类通过abstract关键字定义。
  2. 抽象方法不能用 abstract 声明,Dart中没有方法体的方法我们称为抽象方法。
  3. 如果子类继承抽象类必须得实现里面的抽象方法。
  4. 如果把抽象类当作接口实现的话必须得实现抽象类里面定义的所有属性和方法。
  5. 抽象类不能被实例化,只有继承它得子类可以。

extends 抽象类和 implements 的区别:

  1. 如果要复用抽象类里面得方法,并且要用抽象方法约束自类得话我们就用extends继承抽象类
  2. 如果只是把抽象类当作标准得话我们就用implements实现抽象类

多态

父类定义一个方法不去实现,让继承它得子类去实现,每个子类又不同得表现

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

  Cat c = Cat();
  c.eat();
}

abstract class Animal {
  eat();
}

class Dog extends Animal {
  @override
  eat() {
    print('小狗在吃骨头');
  }
}

class Cat extends Animal {
  @override
  eat() {
    print('小猫在吃');
  }
}

子类得实例赋值给父类得引用

void main() {
  Animal d = new Dog();
  d.eat();

  Animal c = Cat();
  c.eat();
}

abstract class Animal {
  eat();
}

class Dog extends Animal {
  @override
  eat() {
    print('小狗在吃骨头');
  }
}

class Cat extends Animal {
  @override
  eat() {
    print('小猫在吃');
  }
}

接口

abstract class Db {
  String? uri;
  add(String data);
  save();
  delete();
}
import 'Db.dart';

class Mysql implements Db {
  @override
  String? uri;

  Mysql(this.uri);

  @override
  add(data) {
    print('这是mysql得add方法' + data);
  }

  @override
  delete() {
    // TODO: implement delete
    throw UnimplementedError();
  }

  @override
  save() {
    // TODO: implement save
    throw UnimplementedError();
  }
}
import 'Db.dart';

class MsSql implements Db {
  @override
  String? uri;

  @override
  add(data) {
    print('这是mssql得add方法' + data);
  }

  @override
  delete() {
    // TODO: implement delete
    throw UnimplementedError();
  }

  @override
  save() {
    // TODO: implement save
    throw UnimplementedError();
  }
}

一个类实现多个接口

void main() {
  C c = C();
  c.printA();
  c.printB();
}

abstract class A {
  String? name;
  printA();
}

abstract class B {
  String? name;
  printB();
}

class C implements A, B {
  @override
  String? name;

  @override
  printA() {
    print('printA');
  }

  @override
  printB() {
    print('printB');
  }
}

Mixin

在类中混入其它功能,可以使用mixins实现类似多继承的功能。

  1. 作为mixins的类只能继承自Object,不能继承其它类
  2. 作为mixins的类不能又构造函数
  3. 一个类可以mixins多个mixins类
  4. mixins绝不是继承,也不是接口,而是一种全选的特性
void main() {
  C c = C('张三', 18);
  c.printA();
  c.printB();
  print(c.label);
  print(c.text);
  print(c.name);
  c.printInfo();
}

class Person {
  String? name;
  int age;

  Person(this.name, this.age);

  printInfo() {
    print("${this.name}---${this.age}");
  }
}

mixin A {
  String label = 'this is A';
  void printA() {
    print('printA');
  }
}

mixin B {
  String text = 'this is B';
  void printB() {
    print('printB');
  }
}

class C extends Person with A, B {
  C(String? name, int age) : super(name, age);
}

泛型

泛型就是解决 类 接口 方法的复用性、以及对不特定数据类型的支持(类型检查)

泛型方法

void main() {
  // 不检查类型
  print(getData('Hello'));
  print(getData(123));
  // 检查类型
  print(getData<String>('Hello Dart'));
}

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

泛型类

内置泛型类

void main() {
  List names = <String>[];
  names.addAll(['Seth', 'Kathy', 'Lars']);
}

自定义泛型类

void main() {
  PrintClass p = PrintClass();
  p.add(1);
  p.add(12);
  p.add('Hello');
  p.printList();

  PrintClass p2 = PrintClass<String>();
  //p2.add(1); // 只能传入 String 类型
  p2.add('Hello');
  p2.printList();
}

class PrintClass<T> {
  List list = <T>[];

  void add(T value) {
    this.list.add(value);
  }

  void printList() {
    print(this.list);
  }
}

泛型接口

void main() {
  MemoryCache m1 = MemoryCache<String>();
  m1.setByKey('key', 'value');

  MemoryCache m2 = MemoryCache<Map>();
  m2.setByKey('key', {"name": "张三", "age": 20});

}

abstract class Cache<T> {
  getByKey(String key);
  void setByKey(String key, T value);
}

class FileCache<T> implements Cache<T> {
  @override
  getByKey(String key) {
    return key;
  }

  @override
  void setByKey(String key, T value) {
    print("文件缓存 存储 key=${key}  value=${value}");
  }
}

class MemoryCache<T> implements Cache<T> {
  @override
  getByKey(String key) {
    return key;
  }

  @override
  void setByKey(String key, T value) {
    print("内存缓存 存储 key=${key}  value=${value}");
  }
}

相关推荐

得物可观测平台架构升级:基于GreptimeDB的全新监控体系实践

一、摘要在前端可观测分析场景中,需要实时观测并处理多地、多环境的运行情况,以保障Web应用和移动端的可用性与性能。传统方案往往依赖代理Agent→消息队列→流计算引擎→OLAP存储...

warm-flow新春版:网关直连和流程图重构

本期主要解决了网关直连和流程图重构,可以自此之后可支持各种复杂的网关混合、多网关直连使用。-新增Ruoyi-Vue-Plus优秀开源集成案例更新日志[feat]导入、导出和保存等新增json格式支持...

扣子空间体验报告

在数字化时代,智能工具的应用正不断拓展到我们工作和生活的各个角落。从任务规划到项目执行,再到任务管理,作者深入探讨了这款工具在不同场景下的表现和潜力。通过具体的应用实例,文章展示了扣子空间如何帮助用户...

spider-flow:开源的可视化方式定义爬虫方案

spider-flow简介spider-flow是一个爬虫平台,以可视化推拽方式定义爬取流程,无需代码即可实现一个爬虫服务。spider-flow特性支持css选择器、正则提取支持JSON/XML格式...

solon-flow 你好世界!

solon-flow是一个基础级的流处理引擎(可用于业务规则、决策处理、计算编排、流程审批等......)。提供有“开放式”驱动定制支持,像jdbc有mysql或pgsql等驱动,可...

新一代开源爬虫平台:SpiderFlow

SpiderFlow:新一代爬虫平台,以图形化方式定义爬虫流程,不写代码即可完成爬虫。-精选真开源,释放新价值。概览Spider-Flow是一个开源的、面向所有用户的Web端爬虫构建平台,它使用Ja...

通过 SQL 训练机器学习模型的引擎

关注薪资待遇的同学应该知道,机器学习相关的岗位工资普遍偏高啊。同时随着各种通用机器学习框架的出现,机器学习的门槛也在逐渐降低,训练一个简单的机器学习模型变得不那么难。但是不得不承认对于一些数据相关的工...

鼠须管输入法rime for Mac

鼠须管输入法forMac是一款十分新颖的跨平台输入法软件,全名是中州韵输入法引擎,鼠须管输入法mac版不仅仅是一个输入法,而是一个输入法算法框架。Rime的基础架构十分精良,一套算法支持了拼音、...

Go语言 1.20 版本正式发布:新版详细介绍

Go1.20简介最新的Go版本1.20在Go1.19发布六个月后发布。它的大部分更改都在工具链、运行时和库的实现中。一如既往,该版本保持了Go1的兼容性承诺。我们期望几乎所...

iOS 10平台SpriteKit新特性之Tile Maps(上)

简介苹果公司在WWDC2016大会上向人们展示了一大批新的好东西。其中之一就是SpriteKitTileEditor。这款工具易于上手,而且看起来速度特别快。在本教程中,你将了解关于TileE...

程序员简历例句—范例Java、Python、C++模板

个人简介通用简介:有良好的代码风格,通过添加注释提高代码可读性,注重代码质量,研读过XXX,XXX等多个开源项目源码从而学习增强代码的健壮性与扩展性。具备良好的代码编程习惯及文档编写能力,参与多个高...

Telerik UI for iOS Q3 2015正式发布

近日,TelerikUIforiOS正式发布了Q32015。新版本新增对XCode7、Swift2.0和iOS9的支持,同时还新增了对数轴、不连续的日期时间轴等;改进TKDataPoin...

ios使用ijkplayer+nginx进行视频直播

上两节,我们讲到使用nginx和ngixn的rtmp模块搭建直播的服务器,接着我们讲解了在Android使用ijkplayer来作为我们的视频直播播放器,整个过程中,需要注意的就是ijlplayer编...

IOS技术分享|iOS快速生成开发文档(一)

前言对于开发人员而言,文档的作用不言而喻。文档不仅可以提高软件开发效率,还能便于以后的软件开发、使用和维护。本文主要讲述Objective-C快速生成开发文档工具appledoc。简介apple...

macOS下配置VS Code C++开发环境

本文介绍在苹果macOS操作系统下,配置VisualStudioCode的C/C++开发环境的过程,本环境使用Clang/LLVM编译器和调试器。一、前置条件本文默认前置条件是,您的开发设备已...