搭建Dart
官方推荐地址:https://dart.dev/get-dart
个人建议使用官方提供的安装器安装:https://gekorm.com/dart-windows/
工具 VS Code
安装Code Runner 和 Dart 和 Awesome Flutter Snippets 插件
语法
字符串
main() {
// var 可以定义任何类型变量 自动判断类型
var num = 2;
print(num); // 2
var num1 = 2.2;
print(num1); // 2.2
var str = 2;
print(str); // 2
// 常量 const 在编译期 final 懒执行 在执行前加载 定义固定值两者含义相同
const PI = 3.14;
final PI1 = 3.14;
final TIME = new DateTime.now(); // 2022-06-07 09:07:31.008774
// String 定义字符串
String s = 's';
String s1 = "s1";
// 原样输出
String s2 = '''s2
s2''';
print(s2);
// 字符串拼接
String s = '你';
String s1 = "好";
print(s + s1); // 你好
print('$s $s1'); // 你 好
print("$s $s1"); // 你 好
}
int double
main() {
// int double
int a = 1;
print(a); // 1
double b = 3.1;
print(b); // 3.1
double c = 2;
print(c); // 2.0
print(a + b); // 4.1
print(a + c); // 3.0
print(c + c); // 4.0
// 运算符 + - * / %
print(b - a); // 2.1
print(a * b); // 3.1
print(a / c); // 0.5
print(b % c); // 1.1
// bool 值 true false
bool flag = true;
// 条件判断
if (flag) {
print(flag); // true;
}
// 不对类型转换
var a = 123;
var b = '123';
if (a == b) {
print(true);
} else {
print(false);
}
}
bool
main() {
// bool 值 true false
bool flag = true;
// 条件判断
if (flag) {
print(flag); // true;
}
// 不对类型转换
var a = 123;
var b = '123';
if (a == b) { // false
print(true);
} else {
print(false);
}
}
List (数组/集合)
main() {
// 第一种定义方式
var l1 = ["张三", 20, true];
print(l1); // [张三, 20, true]
print(l1.length); // 3
print(l1[0]); // 张三
// 第二种定义方式 指定类型
var l2 = <String>["张三", "李四", "王五"];
// 第三种定义方式 增加
var l3 = [];
print(l3); // []
l3.add("a");
l3.add(1);
l3.add(1);
l3.add(true);
l3.addAll([1, 2, "3"]);
print(l3); // [a, 1, 1, true, 1, 2, 3]
l3.length = 2; // 更改长度
print(l3); // [a, 1]
// 第四种定义方式 固定长度的集合 不可以.length = 0
var l4 = List.filled(2, "");
print(l4); // [, ]
l4[0] = "a";
print(l4); // [a, ]
var l5 = List<int>.filled(2, 1); // 指定类型int 指定长度2 默认值1
print(l5); // [1, 1]
}
Maps
main() {
// 第一种定义方式 key 必须加""
var person = {
"name": "张三",
"age": 20,
"property": ["run", 1]
};
print(person); // {name: 张三, age: 20, property: [run, 1]}
print(person['name']); // 张三
print(person['property']); // [run, 1]
// 第一种定义方式 Maps
var p = new Map();
p["name"] = "李四";
print(p); // {name: 李四}
}
类型判断
main() {
// 判断类型
var a = 123;
if (a is String) {
print("是字符串");
} else if (a is int) {
print("是int");
} else {
print("不是字符串");
}
}
运算符
main() {
// 算数运算符
int a = 13;
int b = 5;
print(a + b); // 18
print(a - b); // 8
print(a * b); // 65
print(a / b); // 2.6
print(a % b); // 取余 3
print(a ~/ b); // 取整 2
// 关系运算符
print(a == b);
print(a != b);
print(a > b);
print(a < b);
print(a >= b);
print(a <= b);
// 逻辑运算符
bool flag1 = true;
bool flag2 = false;
print(!flag1);
print(flag1 && flag2);
print(flag1 || flag2);
// 赋值运算符 = ??=
int c = 10;
c ??= 1; // 如果c为空 把 1 赋值给c
print(c); // 10
int d;
// d ??= 5; // 报错 原因待查
// 复合赋值运算符 += -= *= /= %= ~/=
int f = 2;
f += 10;
print(f); // 12
f ~/= 5;
print(f); // 2
// 条件表达式
int g = 10;
if (g == 10) {
print(true);
} else {
print(false);
}
switch (g) {
case 10:
print(true);
break;
default:
print(false);
break;
}
// 三目运算符
bool flag = true;
var str = flag ? "t" : "f";
print(str); // t
var t;
var t1 = t ?? 10; // t为空 赋值10
print(t1); // 10
// 类型转换
// Number 与 String 转换
String s = "123";
// String s1 = "123a"; 只能是int类型字符串
// String s2 = "a";
// String s3 = "a123";
// String s4 = "a123b";
var num = int.parse(s);
// var num1 = int.parse(s1);
// var num2 = int.parse(s2);
// var num3 = int.parse(s3);
// var num4 = int.parse(s4);
print(num); // 123
// print(num1);
// print(num2);
// print(num3);
// print(num4);
String gc = '';
var nu;
try {
nu = double.parse(gc);
} catch (e) {
nu = 0;
}
print(nu); // 0
var myNum = 12;
String myString = myNum.toString();
}
循环
main() {
// for循环
for (var i = 0; i < 10; i++) {
print(i);
}
// while 循环
bool flag = true;
while (flag) {
print(flag);
}
do {
print(flag);
} while (flag);
}
forEach map
main() {
// forEach
var li = ['a', 'b', 'a'];
li.forEach((value) {
print(value);
});
var li1 = [1, 2, 3];
var newList = li1.map((value) => value * 2);
print(newList); // (2, 4, 6)
print(newList.toList()); // [2, 4, 6]
var m = {"name": "张三", "age": "20"};
m.forEach((key, value) {
print("$key ==== $value");
});
Map<String, String> ma = m.map((key, value) => new MapEntry(key, value));
Map<String, String> mb = m.map((key, value) {
return new MapEntry(key, value);
});
print(ma); // {name: 张三, age: 20}
print(mb); // {name: 张三, age: 20}
var li2 = [1, 2, 3, 5, 7];
var li3 = li2.where((value) => value > 5);
print(li3); // 7
var li4 = li2.any((value) => value > 5);
print(li4); // true 有满足条件的就反回ture
var li5 = li2.every((value) => value > 5);
print(li5); // false 全部满足条件反回ture
}
方法
main() {
// 方法
/*
返回类型 方法名称 ([类型] 参数1,[类型] 参数2,...) {
方法体
return 返回值;
}
可选参数 [int age, String name]
返回类型 方法名称 ([类型] 参数1,[[类型] 参数2,[类型] 参数3,...]) {
方法体
return 返回值;
}
*/
myFunction(1); // 自定义方法 1
// getNum(); // 未定义
int getNum() {
return 123;
}
print(getNum()); // 123
// 可选参数 ** 如果不写默认值报错 不知道是不是因为新版的问题
void myFunc1(String name, [int age = 0, String sex = "男"]) {
print(name);
}
myFunc1("张三", 2);
// 命名参数 ** 如果不写默认值报错 不知道是不是因为新版的问题
void myFunc(String name, {int age = 0}) {
print(name);
}
myFunc("李四", age: 1);
// 匿名方法
var printNum = (int a) {
print(a);
};
// 自执行方法
((int n) {
print("自执行方法 $n");
})(12);
// 递归
int sum = 0;
void fn(int a) {
sum += a;
if (a < 1) {
return;
}
fn(a - 1);
}
fn(5);
print(sum); // 15
}
void myFunction(int a) {
print("自定义方法 $a");
}
闭包
void main(List<String> args) {
// 闭包 函数嵌套函数,内部函数会调用外部函数的变量或参数
// 全局变量常驻内存 污染全局
// 局部变量不常驻内存 不污染全局 会被垃圾回收机制回收
// 想实现的功能
// 1 常驻内存
// 2 不污染全局
fn() {
var a = 123;
return () {
a++;
print(a);
};
}
// 类似于定义了一个类 返回自己的实例
var b = fn();
b(); // 124
b(); // 125
}
类
class Person {
String name = "张三";
int age = 23;
// 静态属性
static String sex = "男";
static void run() {
print("静态方法");
}
// 私有属性只需要在属性名前加 _
String _gfName = "ab";
Person() {
print("默认构造函数");
}
// 初始化参数
// Person()
// : age = 10,
// name = "李四" {
// print("默认构造函数");
// }
// 只能有一个默认构造函数 不能重载
// Person(String name, int age) {
// this.name = name;
// this.age = age;
// }
// 构造函数简写方式
// Person(this.name, this.age);
// 命名构造函数 可以有多个
Person.now() {
print("命名构造函数");
}
// 命名构造函数简写
Person.setInfo(this.name, this.age);
void getInfo() {
print("$name === $age"); // 张三 === 23
print("${this.name} == ${this.age}"); // 张三 == 23
}
void setInfo(int age) {
this.age = age;
}
// 私有方法
void _run() {
print("私有方法");
}
// 调用的时候使用 xx.getAge; 不加()
get getAge{
return 2 * 2;
}
// 调用的时候使用 xx.myAge = 1;
set myAge(int age) {
this.age = age;
}
}
void main(List<String> args) {
Person p1 = new Person();
// p1.setInfo(11);
p1.getInfo();
print(p1.toString()); // Instance of 'Person'
Person p2 = Person.now();
p2.getInfo();
Person p3 = Person.setInfo("王五", 25);
p3.getInfo();
}
继承
// 继承
class Parent {
String name = "张三";
int age = 22;
Parent(this.name, this.age);
void printInfo() {
print("${this.name} ==== ${this.age}");
}
}
class Son extends Parent {
// 父类构造方法不能继承 需要传参
Son(super.name, super.age);
@override
void printInfo() {
print("覆写");
// 调用父类方法
super.printInfo();
}
}
抽象类 接口 多态
// dart没有Interface 所以接口和抽象类都用abstract
abstract class Animal {
eat(); // 抽象方法
printInfo() {
print("抽象类的普通方法");
}
}
class Cat implements Animal {
@override
eat() {
print("猫");
}
@override
printInfo() {
// 使用 implements 貌似需要把所有方法都要重写
}
}
class Dog extends Animal {
@override
eat() {
print("狗");
}
}
void main(List<String> args) {
// 多态 父类引用指向子类对象
Animal dog = new Dog();
dog.eat();
}
mixins 多继承 使用with
abstract class A {
printA();
}
abstract class B {
printB();
}
// 多实现
class C implements A, B {
@override
printA() {
print("AAA");
}
@override
printB() {
print("BBB");
}
}
class Person {
Person();
printInfo() {
print("Person");
}
}
class E {
String info = "aa";
printE() {
print("EE");
}
}
class F {
printF() {
print("FF");
}
}
// mixins类似多继承
// 被继承的类 E和F 必须只能继承自Object
// 且不能有构造函数 如果 Person E F 含义相同的方法 使用最后一个
class D extends Person with E, F {}
void main(List<String> args) {
D d = new D();
d.printE(); // EE
d.printF(); // FF
print(d.info); // aa
d.printInfo(); // Person
}
泛型
String getData(String data) {
return data;
}
int getData1(int data) {
return data;
}
T getData2<T>(T data) {
return data;
}
class MyList<T> {
List<T> list = [];
void add(T value) {
list.add(value);
}
List getList() {
return this.list;
}
}
void main(List<String> args) {
print(getData2(1)); // 1
print(getData2<int>(2)); // 2
// print(getData2<String>(3)); // 报错 泛型不匹配
MyList myList = MyList();
myList.add(1);
myList.add(2);
myList.add("a");
print(myList.getList()); // [1, 2, a]
MyList<String> myList1 = MyList();
myList1.add("a");
}
工具类 HttpClient
import 'dart:convert';
import 'dart:io';
/*
async 和 await
只有async方法才能使用await关键字调用方法
如果调用别的async方法必须使用await关键字
async 让方法变成异步
await 等待异步方法执行完毕
*/
void main(List<String> args) async {
var result = await _getDataFromZhihuApi();
print(result);
}
_getDataFromZhihuApi() async {
// 1.创建HttpClient对象
var httpClient = new HttpClient();
// 2.创建Uri对象
var uri = new Uri.http('news-at.zhihu.com', '/api/3/stories/latest');
// 3.发起请求,等待请求
var request = await httpClient.getUrl(uri);
// 4.关闭请求,等待响应
var response = await request.close();
// 5.解码响应的内容
return await response.transform(utf8.decoder).join();
}
pub包管理系统
1.从下面网址找要用的库
https://pub.dev/packages
https://pub.flutter-io.cn/packages
https://pub.dartlang.org/flutter
2.创建一个pubspec.yaml文件
name: http
description: This is a description
environment:
sdk: '>=2.10.0 <3.0.0'
dependencies:
date_format: ^2.0.6
3.配置dependencies
4.在vscode中自动dart pub get 否则需要在cmd中运行dart pub get 获取远程库
5.看文档引入库使用
包冲突
import 'lib/Person.dart' as lib;
main() {
lib.Parent p = new lib.Parent("name", 2);
}
部分引入
import 'lib/Person.dart' show getAge;
void main(List<String> args) {
getAge(); // getAge
// getName(); // 没有引入
}
隐藏引入
import 'lib/Person.dart' hide getAge;
void main(List<String> args) {
// getAge(); // 没有引入
getName(); // getName
}
延迟加载 分片
暂无知识
空安全? 和 类型断言! 版本不支持 待查
void main(List<String> args) {
String? username = "张三";
username = null;
print(username!.length);
}
延迟初始化 late 无效 待查
class Person {
late String name;
late int age;
// Person(this.name, this.age);
void setInfo(String name, int age) {
this.name = name;
this.age = age;
}
void getInfo() {
print("${this.name} ---- ${this.age}");
}
}
void main(List<String> args) {
Person person = new Person();
person.setInfo("张三", 23);
person.getInfo();
}