一直觉得自己写的不是技术,而是情怀,一个个的教程是自己这一路走来的痕迹。靠专业技能的成功是最具可复制性的,希望我的这条路能让你们少走弯路,希望我能帮你们抹去知识的蒙尘,希望我能帮你们理清知识的脉络,希望未来技术之巅上有你们也有我。
Dart的基础法语来自下面的网站学习。
也可以下载 (flutter示例+) app学习
本人使用VSCode软件开发。安装VSCode之后,需要安装Dart的语法:
$ brew tap dart-lang/dart
$ brew install dart
在VSCode安装两个插件:
dart
dart第三方用于语法提示的,我觉得使用起来一般般,语法没什么提示效果
code runner
用于右键运行代码
如果关机之后,重新打开软件,发现右键没有run code运行代码的话。可以把code runner第三方删除它后重新安装。
搭建完之后写一个 hello 代码试试
main() {
print('你好 dart');
int age = 20;
String sex = '女';
print('age:$age --- sex:$sex');
}
变量规则
//dart 能够自动推到类型
var str_0 = 'this is var';
print(str_0); //this is var
String str_1 = 'this is string';
print(str_1); //this is string
int str_2 = 123;
print(str_2); //123
final name = 'bob';
print(name); //bob
final String nickName = 'boby';
print(nickName); //boby
const bar = 1000;
print(bar); //1000
const double atm = 1.01 * bar;
print(atm); //1010.0
var stringValue = '';
strngValue = 456;
print(strngValue); //Error: Getter not found: 'strngValue'. 类型会自动校验
类型数据
var clapping = '\u{1f44f}';
print(clapping); //👏
print(clapping.codeUnits); //[55357, 56399]
print(clapping.runes.toList()); //[128079]
//字符串拼接
String str1 = '你好';
String str2 = 'dart';
print(str1 + str2); //你好dart
int a = 123;
a = 45;
print(a); //45
double b = 123.12;
b = 45.34;
print(b); //5.34
bool flag_0 = true;
flag_0 = false;
print(flag_0); //false
var flag_1 = true;
flag_1 = false;
print(flag_1); //false
var flag_2 = true;
if (flag_2) {
print('真'); //真
} else {
print('假');
}
var str3 = '123';
var num4 = 123;
if (str3 == num4) {
print('真');
} else {
print('假'); //假 因为不同类型
}
var str4 = 456;
var num5 = 456;
if (str4 == num5) {
print('真'); //真 类型一样才有意义
} else {
print('假');
}
var list0 = new List();
list0.add('zhangsan');
list0.add('lisi');
print(list0); //[zhangsan, lisi]
var list1 = ['1', '2', '3'];
print(list1); //[1, 2, 3]
print(list1.length); //3
print(list1[1]); //2
var list2 = new List<Stirng>();
list2.add('liubei');
list2.add(789);//Error: 'Stirng' isn't a type.
print(list2);
字典1
var person = {
'name': 'zhangsan',
'age': 20,
'work': ['chengxuyuan', 'waimai']
};
print(person);//{name: zhangsan, age: 20, work: [chengxuyuan, waimai]}
print(person['name']);//zhangsan
print(person['age']);//20
print(person['work']);//[chengxuyuan, waimai]
字典2
var p = new Map();
p['name'] = 'lisi';
p['age'] = 18;
p['work'] = ['1', 'a'];
print(p);//{name: lisi, age: 18, work: [1, a]}
print(p['age']);//18
判断类型
var str = 123;
if (str is String) {
print('string类型');
} else if (str is int) {
print('int类型');//int类型
} else {
print('其他类型');
}
运算表达式
// 算数运算
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
var c = a * b;
print(c);//65
// 关系运算符
int a = 5;
int b = 3;
print(a == b); //false
print(a != b); //true
print(a > b); //true
print(a < b); //false
print(a >= b); //true
print(a <= b); //false
if (a > b) {
print('a大于b');//a大于b
} else {
print('a小于b');
}
// 逻辑运算符
bool flag = false;
print(!flag); //取反
bool a = true;
bool b = true;
print(a && b);
bool c = false;
bool d = false;
print(c || d);
&&判断
int age = 20;
String sex = '女';
if (age == 20 && sex == '女') {
print('age:$age --- sex:$sex');//age:20 --- sex:女
} else {
print('no message');
}
||判断
int age = 23;
String sex = '女';
if (age == 20 || sex == '女') {
print('age:$age --- sex:$sex');//age:23 --- sex:女
} else {
print('no message');
}
// 基础赋值运算符 = ??=
int a = 10;
int b = 3;
int c = a + b;
// b??=23 表示如果b为空的话把23赋值给b
int d=6;
d??=23;
print(d);//6
int e;
e??=23;
print(e);//23
// 符合赋值运算符 += -= *= /= %= ~/=
var a = 12;
a = a + 10;
print(a);//22
var b = 13;
b += 10;
print(b);//23
var c = 4;
c *= 3;
print(c);//12
// 条件表达式 if else switch case
bool flag = true;
if (flag) {
print('true');//true
} else {
print('false');
}
// 判断一个人的成绩
var score = 41;
if (score > 90) {
print('优秀');
} else if (score > 70) {
print('良好');
} else if (score >= 60) {
print('合格');
} else {
print('不合格');
}
// 判断一个人的成绩
var sex = '女';
switch (sex) {
case '女':
print('女');//女
break;
case '男':
print('男');
break;
default:
print('传入参数');
break;
}
// 三木运算
//普通
var flag_0 = true;
var c;
if (flag_0) {
c = 'true';//true
} else {
c = 'false';
}
print(c);
//三木
bool flag_1 = false;
String d = flag_1 ? 'true' : 'false';//false
print(d);
//类型转换
String str_0 = '123';
var num_0 = int.parse(str_0);
print(num_0 is int); //true
String str_1 = '123.1';
var num_1 = double.parse(str_1);
print(num_1 is double); //true
//try...catch
String price = '';
try {
var num_2 = double.parse(price);
print(num_2);
} catch (e) {
print(0);//0
}
var num_3 = 12;
var str = num_3.toString();
print(str is String);//true
// 非空判断
var str = '';
if (str.isEmpty) {
print('str空');//str空
} else {
print('str非空');
}
var str_0;
if (str_0 == null) {
print('str_0空');//str_0空
} else {
print('str_0非空');
}
var num_1 = 0 / 0;
if (num_1.isNaN) {
print('num_1.isNaN');//num_1.isNaN
}
循环语句
var a = 10;
a++;
print(a); //11
var b = 10;
b--;
print(b); //9
var c = a++;
var d = ++c;
print(c); //12
print(d); //12
for (int i = 1; i <= 10; i++) {
print(i);//1 2 3 4 5 6 7 8 9 10
}
for (int i = 1; i <= 10; i++) {
if (i == 4) {
break;
}
print(i);// 1 2 3
}
var i = 1;
while (i <= 10) {
i = i++;
print(i);
}
数据集合类型
List
List list = [
'xaingzhao',
'pingguo',
'xigua',
'motuoche',
'qiche',
'chuanzhi'
];
print(list[1]); //pingguo
list.add('1');
print(list); //[xaingzhao, pingguo, xigua, 1]
print(list.length); //true 长度
print(list.isEmpty); //true 为空判断
print(list.isNotEmpty); //true 非空判断
print(list.reversed); //(1, xigua, pingguo, xaingzhao) 倒序
var listed = list.reversed.toList();
print(listed); //[1, xigua, pingguo, xaingzhao] 复制数组
print(listed.indexOf('pingguo')); //2 查找数据 找到返回index 找不到返回-1
print(listed.remove('xaingzhao')); //true
print(listed.removeAt(0)); //true 1
listed.fillRange(1, 2, 'bbb'); //修改
print(listed); //[chuanzhi, bbb, motuoche, xigua, pingguo]
listed.insert(0, 'ccc'); //指定位置插入
print(listed); //[chuanzhi, ccc, bbb, motuoche, xigua, pingguo]
var str = listed.join('-');
print(str); //ccc-chuanzhi-bbb-motuoche-xigua-pingguo
print(str is String); //true
var listString = 'a-b-c-d-e';
var list_0 = listString.split('-');
print(list_0);//[a, b, c, d, e]
print(list_0 is List);//true
Map
Map person = {'name': 'zhangsan', 'age': 20};
print(person); //{name: zhangsan, age: 20}
var m = new Map();
m['name'] = 'list';
print(m); //{name: list}
print(person.keys.toList()); //[name, age]
print(person.values.toList()); //[zhangsan, 20]
print(person.isEmpty); //false
print(person.isNotEmpty); //true
// 常用方法
Map person_0 = {'name': 'zhangsan', 'age': 20};
person_0.addAll({
'work': ['1', '2'],
'height': 160,
});
print(person_0); //{name: zhangsan, age: 20, work: [1, 2], height: 160}
print(person_0.remove('height')); //160 利用字典移除高度
print(person_0); //{name: zhangsan, age: 20, work: [1, 2]}
print(person_0.containsValue('zhangsan')); //true
var list_0 = ['0', '1', '2', '3', '4', '5'];
for (var i = 0; i < list_0.length; i++) {
print(list_0[i]); //0 1 2 3 4 5
}
for (var item in list_0) {
print(item); //0 1 2 3 4 5
}
list_0.forEach((value) {
print('$value'); //0 1 2 3 4 5
});
Map person_0 = {'name': 'zhangsan', 'age': 20};
person_0.forEach((key,value) {
print('$key-$value'); //name-zhangsan age-20
});
List list_1 = [1, 2, 3, 4, 5];
var list_2 = list_1.map((value) {
return value * 2;
});
print(list_2.toList()); //[2, 4, 6, 8, 10] 所有元素*2
var list_3 = list_1.where((value) {
return value > 1;
});
print(list_3.toList()); //[2, 3, 4, 5] 筛选大于1的元素
var list_4 = list_1.any((value) {
return value > 1;
});
print(list_4);//true 只要有一个元素满足就返回true
var list_5 = list_1.every((value) {
return value > 1;
});
print(list_5);//false 每个元素满足才返回true
set
var s = new Set();
s.addAll([1, 2, 3]);
s.forEach((value)=>print(value));//1 2 3
方法函数
void printInfo() {
print('i am is print');
}
int getNum() {
var num = 2;
return num;
}
String printUserInfo() {
return 'this is str';
}
List getList() {
return [1, 2, 3];
}
int getNumWithNum(int num) {
return num;
}
String getUserInfo(String userName, int age) {
return '姓名:$userName -- 年龄:$age';
}
//创建一个可选参数的方法
String handle(String userName, [int age]) {
if (age != null) {
return '年龄不为空 $userName $age';
}
return '年龄为空 $userName';
}
// 创建两个可选参数的方法
String handle_0(String userName, [int age, String sex = '男']) {
if (age != null) {
return '年龄不为空 $userName $age sex默认参数-性别:$sex';
}
return '年龄为空 $userName sex有值-性别:$sex';
}
//定义一个方法isEvenNumber来判断一个数是否是偶数
bool isEvenNumber(int num) {
if (num % 2 == 0) {
return true;
}
return false;
}
main() {
print(printInfo); //Closure: () => void from Function 'printInfo': static.
print(getNum); //Closure: () => int from Function 'getNum': static.
print(
printUserInfo); //Closure: () => String from Function 'printUserInfo': static.
print(
getList); //Closure: () => List<dynamic> from Function 'getList': static.
print(getNumWithNum(100)); //100
print(getUserInfo('fenghanxu', 18)); //姓名:fenghanxu -- 年龄:18
print(handle('fenghanxu', 18)); //年龄不为空 fenghanxu 18
print(handle('fenghanxu')); //年龄为空 fenghanxu
print(handle_0('fenghanxu', 12)); //年龄不为空 fenghanxu 12 sex默认参数-性别:男
print(handle_0('fenghanxu', 12, '女')); //年龄不为空 fenghanxu 12 sex默认参数-性别:女
print(isEvenNumber(1));//false
print(isEvenNumber(2));//true
}
闭包
/**
闭包
1.全局变量特点:全局变量常驻内存,全局变量污染全局
2.全局变量的特点:不常驻内存会被垃圾机制回收,不会污染全局
想现实的功能:
1.常驻内存
2.不污染全局
产生了闭包,闭包可以解决这个问题....
闭包:函数嵌套函数,内部函数会调用外部函数的变量或参数,变量或参数不会被系统收回(不会释放内存)
闭包的写法:函数嵌套函数,并return里面的函数,这样就形成了闭包
*/
main() {
fn() {
var a = 123; //不会污染全局 常驻内存
return () {
a++;
print(a);//124
};
}
var b = fn();
b();
}
打印出:124
面向对象
class Animal {
String _name;
int age;
Animal(this._name, this.age);
void printInfo() {
print('${this._name} --- ${this.age}');
}
String getName() {
return this._name;
}
void _run() {
print('这是个私有方法');
}
execRun() {
this._run(); //类里面方法的互相调用
}
}
class Person {
String name;
int age;
//类方法
Person(this.name, this.age);
//类方法
Person.now() {
print('i am is a person class');
}
//类方法 带参数
Person.setInfo(String name, int age) {
this.name = name;
this.age = age;
print('${this.name} -- ${this.age}');
}
//对象方法
void printInfo() {
print('${this.name} -- ${this.age}');
}
}
main() {
Person p1 = new Person('fenghanxu', 18);//fenghanxu -- 18
p1.printInfo();
Person.setInfo('feizai', 12);//feizai -- 12
}
类方法
/**
Dart 中的静态成员
1.使用static关键字来实现类级别的变量和函数
2.(重点)静态方法不能访问非静态属性和方法,非静态方法可以访问静态属性和方法
*/
class Person {
static String name = 'zhangsan';
static void show() {
print(name);
}
}
main() {
print(Person.name);//zhangsan
Person.show();//zhangsan
}
//(重点)静态方法不能访问非静态属性和方法,非静态方法可以访问静态属性和方法
class Person {
static String name = 'zhangsan';
int age = 20;
static void show() {
print(name);
}
/** 非静态方法可以访问静态成员以及非静态成员 */
void printInfo() {
print(name);//访问静态属性
print(this.age);//访问非静态属性
show();//访问静态方法
}
/** 静态方法 */
static void printUserInfo(){
print(name);//静态属性
show();//静态方法
//print(this.age);//静态方法不能访问非静态属性
//this.printInfo();//静态方法不能访问非静态方法
// printInfo();//静态方法不能访问非静态方法
}
}
main() {
print(Person.name);
Person.show();
Person p = new Person();
p.printInfo();
Person.printUserInfo();
}
/**
类对象操作
? 条件判断符(了解)
as 类型转换
is 类型判断
.. 级联操作 (记住)
*/
未理解
/**
继承
*/
class Person {
String name = 'zhangsan';
num age = 20;
void printInfo() {
print('${this.name} -- ${this.age}');
}
}
class Web extends Person {}
main() {
Web w = new Web();
print(w.name);//zhangsan
w.printInfo();//zhangsan -- 20
}
/**
关键字 super
*/
class Person {
String name;
num age;
Person(this.name, this.age);
void printInfo() {
print('${this.name} -- ${this.age}');
}
}
class Web extends Person {
Web(String name, num age) : super(name, age) {}
}
main() {
Person p = new Person('lisi', 20);
p.printInfo();//lisi -- 20
Web w = new Web('zhangsan',12);
w.printInfo();//zhangsan -- 12
}
/**
重写父类方法
*/
class Person {
String name;
num age;
Person(this.name, this.age);
void printInfo() {
print('${this.name} -- ${this.age}');
}
work() {
print('${this.name}在工作....');
}
}
class Web extends Person {
Web(String name, num age) : super(name, age);
run() {
print('run');
}
//重写父类方法
@override //可以写也可以不写 建议在重写父类方法的时候加上@override
void printInfo() {
print('name: ${this.name} -- age: ${this.age}');
}
//重写父类方法
@override //可以写也可以不写 建议在重写父类方法的时候加上@override
work() {
print('${this.name}重写父类方法.在工作....');
}
}
main() {
Web w = new Web('lisi', 20);
w.printInfo();//name: lisi -- age: 20
w.work();//lisi重写父类方法.在工作....
}
泛型
/**
泛型 泛型方法
通俗理解:泛型就是解决 类 接口方法的复用性,以及对不特定数据,类型的支持(类型校验)
*/
//只能返回string类型的数据
String getData(String value) {
return value;
}
//同时支持返回string类型同int类型
getData_0(value) {
return value;
}
/**
不指定类型放弃了类型检查,我们现在想实现的是传入什么 返回什么,比喻:传入num类型必须返回num类型 传入string类型必须返回string类型
*/
T getData_1<T>(T value) {
return value;
}
main() {
print(getData_1(21));//21
print(getData_1('xxx'));//xxx
print(getData_1<String>('nihao'));//nihao
print(getData_1<int>(12));//12
}
泛型类
/**
泛型类
*/
class PrintClass<T> {
List list = new List<T>();
void add(T value) {
this.list.add(value);
}
void printInfo() {
for (var i = 0; i < this.list.length; i++) {
print(this.list[i]);
}
}
}
main() {
PrintClass p = new PrintClass();
p.add(1);
p.add('封');
p.add(3);
p.add('niu');
p.printInfo();//1 封 3 niu
}
泛型接口
abstract class Cache<T> {
getByKey(String key);
void setByKey(String key, T value);
}
class MemoryCache<T> implements Cache<T> {
@override
getByKey(String key) {
return null;
}
@override
void setByKey(String key, T value) {
print('key ${key} value ${value}');
}
}
main() {
MemoryCache m = new MemoryCache<Map>();
m.setByKey('index', {'name': 'zhangsan', 'age': 20});//key index value {name: zhangsan, age: 20}
}