Dart介绍
Dart 是一个易用、可移植且高效的语言,适用于在全平台开发高质量的应用程序。由谷歌开发的计算机编程语言,它可以被用于web、服务器、移动应用 和物联网等领域的开发.
Dart环境搭建
bash
windows(推荐):
http://www.gekorm.com/dart-windows/
注意:不是https,如果提示证书有问题,请手动把浏览器中的https改为http,或者联系客服获取Dart Sdk
mac:
如果mac电脑没有安装brew这个工具首先第一步需要安装它: https://brew.sh/
brew tap dart-lang/dart
brew install dartVsCode开发配置
- 找到vscode插件安装dart找到
- vscode插件安装code runner Code Runner 可以运行我们的文件
helloWorld
dart
void main() {
print('Hello, World!');
}main 为入口方法
基础语法
变量
虽然 Dart 是 代码类型安全 的语言,你仍然可以用 var 来定义变量,而不用显式指定它们的类型。由于其支持类型推断,因此大多数变量的类型会由它们的初始化内容决定
dart
var str='this is var';
String str='this is var';
int str=123;注意: var 后就不要写类型 , 写了类型 不要var 两者都写 var a int = 5; 报错
Dart 常量
final 和 const修饰符
- const值不变 一开始就得赋值
- final 可以开始不赋值 只能赋一次 ; 而final不仅有const的编译时常量的特性,最重要的它是运行时常量,并且final是惰性初始化,即在运行时第一次使用前才初始化
dart
final name = 'Bob'; // Without a type annotation
final String nickname = 'Bobby';
const bar = 1000000; // Unit of pressure (dynes/cm2)
const double atm = 1.01325 * bar; // Standard atmosphere数据类型
code
/*
Dart中支持以下数据类型:
常用数据类型:
Numbers(数值):
int
double
Strings(字符串)
String
Booleans(布尔)
bool
List(数组)
在Dart中,数组是列表对象,所以大多数人只是称它们为列表
Maps(字典)
通常来说,Map 是一个键值对相关的对象。 键和值可以是任何类型的对象。每个 键 只出现一次, 而一个值则可以出现多次
项目中用不到的数据类型 (用不到):
Runes
Rune是UTF-32编码的字符串。它可以通过文字转换成符号表情或者代表特定的文字。
main() {
var clapping = '\u{1f44f}';
print(clapping);
print(clapping.codeUnits);
print(clapping.runes.toList());
Runes input = new Runes(
'\u2665 \u{1f605} \u{1f60e} \u{1f47b} \u{1f596} \u{1f44d}');
print(new String.fromCharCodes(input));
}
Symbols
Symbol对象表示在Dart程序中声明的运算符或标识符。您可能永远不需要使用符号,但它们对于按名称引用标识符的API非常有用,因为缩小会更改标识符名称而不会更改标识符符号。要获取标识符的符号,请使用符号文字,它只是#后跟标识符:
在 Dart 中符号用 # 开头来表示,入门阶段不需要了解这东西,可能永远也用不上。
http://dart.goodev.org/guides/libraries/library-tour#dartmirrors---reflection
*/数值类型
dart
//1、int 必须是整型
int a=123;
a=45;
print(a);
//2、double 既可以是整型 也可是浮点型
double b=23.5;
b=24;
print(b);字符串类型
dart
var str1="this is str1";
String str2="this is str2";
print(str1 + str2);布尔类型
dart
bool flag1=true;List(数组/集合)
dart
var l1=["张三",20,true];code
常用属性:
length 长度
reversed 翻转
isEmpty 是否为空
isNotEmpty 是否不为空
常用方法:
add 增加
addAll 拼接数组
indexOf 查找 传入具体值
remove 删除 传入具体值
removeAt 删除 传入索引值
fillRange 修改
insert(index,value); 指定位置插入
insertAll(index,list) 指定位置插入List
toList() 其他类型转换成List
join() List转换成字符串
split() 字符串转化成List
filled(3, a) 创建长度为3的数组, 用a填充
forEach
map
where
any
every过滤数组
dart
List myList=[1,3,4,5,7,8,9];
var newList=myList.where((value){
return value>5;
});
print(newList.toList());Set
Set是没有顺序且不能重复的集合,所以不能通过索引去获取值.
用它最主要的功能就是去除数组重复内容
dart
List myList=['香蕉','苹果','西瓜','香蕉','苹果','香蕉','苹果'];
var s=new Set();
s.addAll(myList);
print(s);
print(s.toList());Maps(字典)
dart
var person={
"name":"张三",
"age":20,
"work":["程序员","送外卖"]
};
print(person);
print(person["name"]);
print(person["age"]);
print(person["work"]);code
常用属性:
keys 获取所有的key值
values 获取所有的value值
isEmpty 是否为空
isNotEmpty 是否不为空
常用方法:
remove(key) 删除指定key的数据
addAll({...}) 合并映射 给映射内增加属性
containsValue 查看映射内的值 返回true/false
forEach
map
where
any
every判断数据类型
is 关键词来判断类型
dart
var str=123;
if(str is String){
print('是string类型');
}else if(str is int){
print('int');
}else{
print('其他类型');
}类型转换
Number与String类型之间的转换
dart
/// Number类型转换成String类型 toString()
var myNum=12;
var str=myNum.toString();
print(str is String);
// String类型转成Number类型 int.parse()
String price='12';
var myNum=double.parse(price);
print(myNum);
print(myNum is double);运算符
算术运算符
dart
+ - * / ~/ (取整) %(取余)关系运算符
dart
== != > < >= <=逻辑运算符
&& 不存在JS中的短路逻辑
dart
// ! && ||
bool flag=false;
print(!flag); //取反
----------
int age=20;
String sex="女";
if(age==20 && sex=="女"){
print("$age --- $sex");
}else{
print("不打印");
}
-----------
int age=23;
String sex="女";
if(age==20 || sex=="女"){
print("$age --- $sex");
}else{
print("不打印");
}赋值运算符
dart
//基础赋值运算符 = ??=
//复合赋值运算符 += -= *= /= %= ~/=
b??=23; // 表示如果b为空的话把 23赋值给b
a = b ?? 23; // 兜底 23三目运算符
dart
bool flag=false;
String c=flag?'我是true':'我是false';
print(c);自运算
dart
// ++ -- 表示自增 自减
// 在赋值运算里面 如果++ -- 写在前面 这时候先运算 再赋值,如果++ --写在后面 先赋值后运行运算条件控制语句
if
DART
bool flag=true;
if(flag){
print('true');
}else{
print('false');
}switch
dart
var sex="女";
switch(sex){
case "男":
print('性别是男');
break;
case "女":
print('性别是女');
print('性别是女');
break;
default:
print('传入参数错误');
break;
}for
dart
for (int i = 1; i<=100; i++) {
print(i);
}while
dart
int i=1;
while(i<=10){
print(i);
i++;
}跳出
break continue , 同 JS java
函数
code
内置方法/函数:
print();
自定义方法:
自定义方法的基本格式:
返回类型 方法名称(参数1,参数2,...){
方法体
return 返回值;
}dart
void printInfo(){
print('我是一个自定义方法');
}
int getNum(){
var myNum=123;
return myNum;
}
String printUserInfo(){
return 'this is str';
}
List getList(){
return ['111','2222','333'];
}带参数
dart
int sumNum(int n){
var sum=0;
for(var i=1;i<=n;i++)
{
sum+=i;
}
return sum;
}
var n1=sumNum(5);
print(n1);
var n2=sumNum(100);
print(n2);参数默认值
dart
String printUserInfo(String username, [String sex = '男', int age = 0]) {
if (age != 0) {
return "姓名:$username---性别:$sex--年龄:$age";
}
return "姓名:$username---性别:$sex--年龄保密";
}
print(printUserInfo('张三'));
print(printUserInfo('小李', '女'));
print(printUserInfo('小李', '女', 30));方法可以作为一个参数
dart
fn2(fn) {
fn();
}箭头函数
箭头函数内只能写一条语句
dart
// 报错
list.forEach((value)=>{
print(value);
});
// 正确
list.forEach((value)=>print(value));
var newList=list.map((value)=>value>2?value*2:value);递归函数
dart
fn(int n){
sum+=n;
if(n==0){
return;
}
fn(n-1);
}立即执行函数
dart
((int n){
print(n);
print('我是自执行方法');
})(12);闭包
与JS一模一样
dart
fn() {
var a = 123; /*不会污染全局 常驻内存*/
return () {
a++;
print(a);
};
}面向对象OOP
面向对象编程(OOP)的三个基本特征是:封装、继承、多态 ;
Dart所有的东西都是对象,所有的对象都继承自Object类。
类的使用
创建类
dart
class Person{
String name="张三";
int age=23;
void getInfo(){
// print("$name----$age");
print("${this.name}----${this.age}");
}
void setInfo(int age){
this.age=age;
}
}
void main(){
//实例化
Person p1=new Person();
// print(p1.name);
p1.setInfo(28);
p1.getInfo();
}默认构造函数
dart
class Person{
String name='张三';
int age=20;
//默认构造函数
Person(){
print('这是构造函数里面的内容 这个方法在实例化的时候触发');
}
void printInfo(){
print("${this.name}----${this.age}");
}
}
class Person{
late String name;
late int age;
//默认构造函数的简写
Person(this.name,this.age);
void printInfo(){
print("${this.name}----${this.age}");
}
}命名构造函数
dart
class Person {
late String name;
late int age;
//默认构造函数的简写
Person(this.name, this.age);
Person.now() {
print('我是命名构造函数');
}
Person.setInfo(String name, int age) {
this.name = name;
this.age = age;
}
void printInfo() {
print("${this.name}----${this.age}");
}
}
void main() {
Person p1 = new Person.setInfo('李四', 30);
p1.printInfo();
}私有方法/属性
dart
//使用 _ 把一个属性或者方法定义成私有。
class Animal{
late String _name; //私有属性;
//默认构造函数的简写
Animal(this._name);
void _run(){
print('这是一个私有方法');
}
execRun(){
this._run(); //类里面方法的相互调用
}
}get/set
dart
class Rect{
num height;
num width;
Rect(this.height,this.width);
get area{
return this.height*this.width;
}
}
void main(){
Rect r=new Rect(10,2);
print("面积:${r.area}"); //注意调用直接通过访问属性的方式访问area
}
class Rect{
late num height;
late num width;
Rect(this.height,this.width);
get area{
return this.height*this.width;
}
set areaHeight(value){
this.height=value;
}
}
void main(){
Rect r=new Rect(10,4);
// print("面积:${r.area()}");
r.areaHeight=6;
print(r.area);
}始化实例变量
dart
// Dart中我们也可以在构造函数体运行之前初始化实例变量
class Rect{
int height;
int width;
Rect():height=2,width=10{
print("${this.height}---${this.width}");
}
getArea(){
return this.height*this.width;
}
}
class Rect{
int height = 2;
int width = 10;
Rect(){
print("${this.height}---${this.width}");
}
getArea(){
return this.height*this.width;
}
}
void main(){
Rect r=new Rect();
print(r.getArea());
}静态成员
- 使用static 关键字来实现类级别的变量和函数
- 静态方法不能访问非静态成员,非静态方法可以访问静态成员
dart
class Person {
static String name = '张三';
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();
}对象操作符
code
? 条件运算符 (了解) https://dart.dev/tools/diagnostic-messages#invalid_null_aware_operator
as 类型转换
is 类型判断
.. 级联操作 (连缀) (记住) 在同一个对象上连续调用多个方法或设置多个属性,而不需要重复引用该对象dart
p?.printInfo();
if(p is Person){
p.name="李四";
(p as Person).printInfo();
}
// 链式调用
Person p1 = new Person('张三1', 20);
p1.printInfo();
p1
..name = "李四"
..age = 30
..printInfo();继承
1、子类使用extends关键词来继承父类
2、子类会继承父类里面可见的属性和方法 但是不会继承构造函数
3、子类能复写父类的方法 getter和setter
简单继承
dart
class Person {
String name='张三';
num age=20;
void printInfo() {
print("${this.name}---${this.age}");
}
}
class Web extends Person{
}
main(){
Web w=new Web();
print(w.name);
w.printInfo();
}super调用父类构造器
dart
class Person {
String name;
num age;
Person(this.name,this.age);
Person.xxx(this.name, this.age); //命名构造器
void printInfo() {
print("${this.name}---${this.age}");
}
}
class Web extends Person{
late String sex;
Web(String name, num age,String sex) : super(name, age){
this.sex=sex;
}
Web(String name, num age, String sex) : super.xxx(name, age) {
this.sex = sex;
}
run(){
print("${this.name}---${this.age}--${this.sex}");
}
}覆写父类的方法
dart
class Web extends Person{
Web(String name, num age) : super(name, age);
run(){
print('run');
}
//覆写父类的方法
@override //可以写也可以不写 建议在覆写父类方法的时候加上 @override
void printInfo(){
print("姓名:${this.name}---年龄:${this.age}");
}
@override
work(){
print("${this.name}的工作是写代码");
}
}子类调用父类的方法
dart
class Web extends Person{
Web(String name, num age) : super(name, age);
run(){
print('run');
super.work(); //子类调用父类的方法
}
}抽象类
extends抽象类 和 implements的区别:
1、如果要复用抽象类里面的方法,并且要用抽象方法约束自类的话我们就用extends继承抽象类
2、如果只是把抽象类当做标准的话我们就用implements实现抽象类
dart
abstract class Animal{
eat(); //抽象方法
run(); //抽象方法
printInfo(){
print('我是一个抽象类里面的普通方法');
}
}
class Dog extends Animal{
@override
eat() {
print('小狗在吃骨头');
}
@override
run() {
print('小狗在跑');
}
}接口
不写方法体,不初始值的抽象类在dart叫接口
dart
abstract class Db{ //当做接口 接口:就是约定 、规范
late String uri; //数据库的链接地址
add(String data);
save();
delete();
}
class MsSql implements Db{
@override
late String uri;
@override
add(String data) {
print('这是mssql的add方法'+data);
}
@override
delete() {
return null;
}
@override
save() {
return null;
}
}泛型
dart
// 泛型方法
getData<T>(T value){
return value;
}
// 泛型类
class MyList<T> {
List list = <T>[];
void add(T value) {
this.list.add(value);
}
List getList() {
return list;
}
}
// 泛型接口
abstract class Cache<T> {
getByKey(String key);
void setByKey(String key, T value);
}库
code
Dart中的库主要有三种:
1、我们自定义的库
import 'lib/xxx.dart';
2、系统内置库
import 'dart:math';
import 'dart:io';
import 'dart:convert';
3、Pub包管理系统中的库
https://pub.dev/packages
https://pub.flutter-io.cn/packages
https://pub.dartlang.org/flutter/
1、需要在自己想项目根目录新建一个pubspec.yaml
2、在pubspec.yaml文件 然后配置名称 、描述、依赖等信息
3、然后运行 pub get 获取包下载到本地
4、项目中引入库 import 'package:http/http.dart' as http; 看文档使用async await
dart
void main() async{
var result = await testAsync();
print(result);
}as
dart
import 'lib/Person1.dart';
import 'lib/Person2.dart' as lib;
main(List<String> args) {
Person p1=new Person('张三', 20);
p1.printInfo();
lib.Person p2=new lib.Person('李四', 20);
p2.printInfo();
}部分导入
show 只导入需要的部分
dart
// 只导入 foo
import 'package:lib1/lib1.dart' show foo;hide 排除不要的部分
dart
// 除了 foo 都导入
import 'package:lib2/lib2.dart' hide foo;延迟加载
dart
//懒加载使用deferred as关键字来指定,如下例子所示:
import 'package:deferred/hello.dart' deferred as hello;
//当需要使用的时候,需要使用loadLibrary()方法来加载:
greet() async {
await hello.loadLibrary();
hello.printGreeting();
}