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

Dart简易入门基础 dart教程

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

变量类型

// 通过 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}");
  }
}

相关推荐

当Frida来“敲”门(frida是什么)

0x1渗透测试瓶颈目前,碰到越来越多的大客户都会将核心资产业务集中在统一的APP上,或者对自己比较重要的APP,如自己的主业务,办公APP进行加壳,流量加密,投入了很多精力在移动端的防护上。而现在挖...

服务端性能测试实战3-性能测试脚本开发

前言在前面的两篇文章中,我们分别介绍了性能测试的理论知识以及性能测试计划制定,本篇文章将重点介绍性能测试脚本开发。脚本开发将分为两个阶段:阶段一:了解各个接口的入参、出参,使用Python代码模拟前端...

Springboot整合Apache Ftpserver拓展功能及业务讲解(三)

今日分享每天分享技术实战干货,技术在于积累和收藏,希望可以帮助到您,同时也希望获得您的支持和关注。架构开源地址:https://gitee.com/msxyspringboot整合Ftpserver参...

Linux和Windows下:Python Crypto模块安装方式区别

一、Linux环境下:fromCrypto.SignatureimportPKCS1_v1_5如果导包报错:ImportError:Nomodulenamed'Crypt...

Python 3 加密简介(python des加密解密)

Python3的标准库中是没多少用来解决加密的,不过却有用于处理哈希的库。在这里我们会对其进行一个简单的介绍,但重点会放在两个第三方的软件包:PyCrypto和cryptography上,我...

怎样从零开始编译一个魔兽世界开源服务端Windows

第二章:编译和安装我是艾西,上期我们讲述到编译一个魔兽世界开源服务端环境准备,那么今天跟大家聊聊怎么编译和安装我们直接进入正题(上一章没有看到的小伙伴可以点我主页查看)编译服务端:在D盘新建一个文件夹...

附1-Conda部署安装及基本使用(conda安装教程)

Windows环境安装安装介质下载下载地址:https://www.anaconda.com/products/individual安装Anaconda安装时,选择自定义安装,选择自定义安装路径:配置...

如何配置全世界最小的 MySQL 服务器

配置全世界最小的MySQL服务器——如何在一块IntelEdison为控制板上安装一个MySQL服务器。介绍在我最近的一篇博文中,物联网,消息以及MySQL,我展示了如果Partic...

如何使用Github Action来自动化编译PolarDB-PG数据库

随着PolarDB在国产数据库领域荣膺桂冠并持续获得广泛认可,越来越多的学生和技术爱好者开始关注并涉足这款由阿里巴巴集团倾力打造且性能卓越的关系型云原生数据库。有很多同学想要上手尝试,却卡在了编译数据...

面向NDK开发者的Android 7.0变更(ndk android.mk)

订阅Google官方微信公众号:谷歌开发者。与谷歌一起创造未来!受Android平台其他改进的影响,为了方便加载本机代码,AndroidM和N中的动态链接器对编写整洁且跨平台兼容的本机...

信创改造--人大金仓(Kingbase)数据库安装、备份恢复的问题纪要

问题一:在安装KingbaseES时,安装用户对于安装路径需有“读”、“写”、“执行”的权限。在Linux系统中,需要以非root用户执行安装程序,且该用户要有标准的home目录,您可...

OpenSSH 安全漏洞,修补操作一手掌握

1.漏洞概述近日,国家信息安全漏洞库(CNNVD)收到关于OpenSSH安全漏洞(CNNVD-202407-017、CVE-2024-6387)情况的报送。攻击者可以利用该漏洞在无需认证的情况下,通...

Linux:lsof命令详解(linux lsof命令详解)

介绍欢迎来到这篇博客。在这篇博客中,我们将学习Unix/Linux系统上的lsof命令行工具。命令行工具是您使用CLI(命令行界面)而不是GUI(图形用户界面)运行的程序或工具。lsoflsof代表&...

幻隐说固态第一期:固态硬盘接口类别

前排声明所有信息来源于网络收集,如有错误请评论区指出更正。废话不多说,目前固态硬盘接口按速度由慢到快分有这几类:SATA、mSATA、SATAExpress、PCI-E、m.2、u.2。下面我们来...

新品轰炸 影驰SSD多款产品登Computex

分享泡泡网SSD固态硬盘频道6月6日台北电脑展作为全球第二、亚洲最大的3C/IT产业链专业展,吸引了众多IT厂商和全球各地媒体的热烈关注,全球存储新势力—影驰,也积极参与其中,为广大玩家朋友带来了...