前世今生
Dart是种编程语言,谷歌儿子之一,目前很火的跨平台开发框架Flutter采用的就是Dart,至于前世今生自行百度/Google即可。
环境搭建
- 这里我只发出Dart的下载网站,其他的可以看一下网站。https://dart.dev/get-dart
数据类型
- 入口函数:
void main() {
var test = 0;
print(test);
}
- 定义常量与变量:使用var声明任意类型变量,使用const声明常量,变量未赋值时默认为null,final声明的变量只能赋值一次:
void main() {
var test = 0;
const haha = "哈哈哈";
final heihei = "666";
print(test);
}
- 数据类型有:数值型-Number;布尔型-Boolean;键值对-Map;字符串-String;列表-List。
test() { //返回类型可以省略
num a = 0;
int b = 1;
double c = 1.0;
//常用运算操作
a + b;
a - b;
a * b;
b / c; //整除
b % c; //
b ~/ c; //除
//常用方法
a.isNaN; //非数字
a.isOdd; //是否是奇数
a.isEven; //是否是偶数
double d = 1.0;
d.abs();
d.round();
d.floor();
d.ceil();
d.toInt();
b.toDouble();
//字符串
var e = 'a';
var f = "b";
var g = '''
apfpafpafpaf
fakfkas;fk;dfk
sadfjafjafjs
'''; //多行字符串
var h = r'hello \n dart'; //是将\n转意符号打印出来 使其不生效 这种叫做raw字符串
//字符串操作
e + f;
e * 3; //3倍的e
e == f;
g[1];
print("e + f = ${e + f}"); //插值操作
//常用属性
g.length;
g.isEmpty;
g.isNotEmpty;
//常用方法
g.contains(e);
g.substring(10);
g.toLowerCase();
g.toUpperCase();
g.trim();
g.trimLeft();
g.trimRight();
g.replaceXXXXX(); //以replace开发头的部分方法
g.startsWith(pattern);
g.endsWith(pattern);
g.indexOf(pattern);
g.lastIndexOf(pattern);
g.split(pattern);
//布尔型
bool isTrue = true;
isTrue = false;
//List数组
var list = [1, 2, 3];
var list1 = const [1, 2, 3]; //不可变list
var list2 = new List(); //dart中new可以省略
//常用操作
list.length;
list.add(4);
list.insert(0, 5);
list.remove(1);
list.clear();
list.indexOf(2);
list.lastIndexOf(3);
list.sort();
list.sublist(2);
list.shuffle();
list.asMap();
list.forEach(print); //这里面传递的是一个方法,比如print
//Map字典
var map = {'first':'Dart','second':'php'};
var map1 = const {'first':'Dart','second':'php'}; //不可变map
var map2 = Map();
//常用操作
map.length;
map.isEmpty;
map.isNotEmpty;
map.keys;
map.values;
map.containsKey('first');
map.containsValue('php');
map.remove('first');
map.forEach(print);
//dynamic关键字
dynamic j =20;
j = "javaScript";
var list3 = List< dynamic >();
list3.add(1);
list3.add("hello");
list3.add(true);
print(list3);
}
运算符
- 算术运算符:+ ,- ,* ,/ ,~/ ,% ,++ ,-- 。其实也就 ~/ 比较特殊,就是我们现实中的除法,结果带小数的那种。
- 关系运算符:==,!=,>,<,>=,<=,==
- 逻辑运算符:!,&&,||。主要针对布尔类型进行运算
- 赋值运算符:=,??=,+=,-=,*=,/=,%=,~/=
- 条件表达式:三目运算符 ?:,??运算符 ??。
控制语句
- 流程控制语句
test() {
//条件语句
var a = 10;
var b = 20;
if(a == b) {
print("a=b");
} else {
print("a!=b");
}
//for循环语句
var list = [1, 2, 3, 4, 5];
for(var i = 0; i< list.length; i++) {
print(list[i]);
}
for (var i in list) {
print(i);
}
//while循环语句
var j = 0;
while(j <= 10){
j++;
}
do {
j--;
} while (j <= 0);
//break与continue
//break:终止循环
//continue:跳出当前循环
//switch...case语句
String language = "Dart";
switch (language) {
D: //定义一个标签,这里面可以使用continue跳转
case "Dart":
print("dart");
break;
case "php":
print("php");
continue D;
// break;
case "Java":
print("Java");
break;
default:
print("default");
}
}
方法
- 方法也是对象,并且有具体类型Function,返回值/参数类型都可以省略,箭头语法 => 知识 {return ;} 的缩写,方法都有返回值,如果没有指定,默认返回值是null.
- 方法定义格式
返回值 方法名 (参数1, 参数2) {
方法体
return 返回值
}
printPerson(name, age) {
print("name = $name, age = $age");
}
person(name, age) => "name = $name, age = $age";
- 可选参数
personInfo(String name, {int age}) {
print("name=$name, age=$age");
}
//带默认值的参数
personInfo1(String name, {int age = 10}) {
print("name=$name, age=$age");
}
- 方法对象
//方法可作为对象赋值给其他变量
main() {
var func = printHello();
func();
}
printHello() {
print("Hello");
}
//方法可作为参数传递给其他方法
main() {
var list = ["h","e","l","l","o"];
print(listTimes(list, times));
}
List listTimes(List list, String times(str)) {
for(var index = 0; index < list.length; index ++) {
list[index] = times(list[index]);
}
return list;
}
String times(str) {
return str * 3;
}
- 匿名方法
main() {
var func = (str) {
print(str);
};
func(30);
var list = ["h","e","l","l","o"];
print(listTimes(list, (str) { return str * 3; } ));
}
List listTimes(List list, String times(str)) {
for(var index = 0; index < list.length; index ++) {
list[index] = times(list[index]);
}
return list;
}
- 闭包
//闭包是一个方法,定义再其他方法内部,能够访问外部方法内的局部变量,并持有其状态
main() {
var func = a();
func();
func();
}
a() {
int count = 0;
return {
print(count++);
}
}
面向对象
- 使用class声明一个类,使用new创建类的对象,new可以省略,所有类都继承于基类Object;
- 类中封装了共同特性,叫做属性,默认会生成setter和getter方法,使用final声明的属性只有getter方法,属性和方法通过打点调用,Dart中的方法不能重载;
- Dart中的可见性以library(库)为单位,默认情况下每个Dart文件就是一个库,使用 _ 开头的属性或者方法是私有性的,使用import导入库。
//类
class Person {
String _name;
int age;
final String address;
void work(){
print("name=$_name, age=$age");
}
}
//计算属性
class Rect {
num width, height;
num get area {
return width * height;
}
}
//构造方法
//如果没有自定义构造方法,则会有个默认构造方法;如果存在自定义构造方法,则默认构造方法无效;构造方法不能重载。
//使用命名构造方法,可以实现多个构造方法;使用 类名.方法 的形式实现。
//如果类是不可变的状态,可以把对象定义为编译时常量;使用const声明构造方法,并且所有变量都为final;使用const声明对象,可以省略。
//使用factory修饰的是工厂构造方法。
class Person {
String name;
int age;
final String gender;
//这种构造方法不能给final赋值
Person(String name, int age) {
this.name = name;
this.age = age;
}
//这种可以,因为这个赋值是走在构造方法之前
Person(this.name, this.age, this.gender);
//命名构造函数
Person.withName(String name) {
this.name = name;
}
}
//使用的时候使用const修饰,里面的值都不可变
class Person {
final String name;
final int age;
final String gender;
const Person(this.name, this.age, this.gender);
}
//工厂构造方法
class Logger {
final String name;
static final Map< String, Logger > _cache = < String, Logger > {};
factory Logger(String name) {
if (_cache.containsKey(name)) {
return _cache[name];
} else {
final logger = Logger._internal(name);
_cache[name] = logger;
return logger;
}
}
Logger._internal(this.name);
void log(String msg) {
print(msg);
}
}
//初始化列表,也是解决final不能赋值的问题(跟c++很像啊)
class Person {
final String name;
final int age;
final String gender;
const Person(this.name, this.age, this.gender);
//是因为初始化列表也是在构造函数之前执行的
Person.withMap(Map map) : name = map["name"], age = map["age"], gender = map["gender"] {
}
}
//静态成员
class Person {
static int currentPage = 1;
//常量要用static const来修饰
static const int maxPage = 10;
//不可以访问非静态属性
static void scrollDown() {
currentPage = 1;
print("ScrollDown");
}
//可以访问静态属性
void scrollUp() {
currentPage++;
print("ScrollUp");
}
}
//对象操作符:条件成员访问 ?. ,类型转换 as,是否指定类型:is,is!,级联操作:..
main() {
Person person;
person?.work();
(person as Person).work();
if (person is Person) {
person.work();
}
new Person()..name = "哈哈"..age = 20..work();
}
//如果实现了call()方法,则该类的对象可以作为方法调用
class Person {
String name;
int age;
void call() {
print("name=$name, age=$age");
}
}
main() {
var person Person();
person.name = "111";
person.age = 10;
person();
}
- 继承/多态/抽象类/接口/Mixins/操作符复写
class Person {
String name;
Person(this.name);
Person.withName(this.name);
}
class Student extends Person {
int age;
final String gender;
//单继承,子类会继承父类的属性,不继承构造方法,能够复写父类的方法与setter/getter,初始化列表会先于父类的构造方法执行
//如果父类没有无名无参的构造方法,则子类是需要取显式的去调用父类中的构造方法的
Student(String name, String g) : gender = g, super.withName(name);
}
//抽象类
abstract class Person {
void run();
}
//类中如果有抽象方法(只定义了,没有实现)则该类必须由 abstract 来修饰
//抽象类主要用于被子类去继承 有点类似接口的概念
class Student extends Person {
@override
void run() {
print("Hello");
}
}
//每一个类 都可以被当作接口使用,使用 implements,感觉不太爽啊
class Person {
String name;
int get age => 18;
void run() {
print("person");
}
}
class Student implements Person {
@override
String name;
@override
int get age => null;
@override
void run() {
print("student");
}
}
//Mixins 写法上就是使用 with 关键字,必须要先有extends 才能有with,使用多个 with ,时 当这多个被with的类同时实现了a()方法,则该类真正调用的一定是最后with的那个类的方法,被with的类是不能显示的写构造方法,with 的类只能继承于Object
class Person {
String name;
int get age => 18;
void run() {
print("person");
}
}
class A {
a() {
print("a");
}
}
class B {
a() {
print("b");
}
}
class C {
c() {
print("c");
}
}
class D extends Person with A, B, C {
}
//简单写法
class E = Person with A;
//覆写操作符
class Person {
int age;
Person(this.age);
bool operator > (Person person) {
return this.age > person.age;
}
//对象不支持[]取值,使用操作符覆写可以实现
int operator [](String str) {
if ("age" == str) {
return age;
}
return 0;
}
}
枚举与泛型
//枚举,大家都造
enum Season {
spring,
summer,
autumn,
winter
}
class Utils {
void put< T>(T s) {
print(s);
}
}
小结
学一门新语言一般也就看这些基础东西,很快就看完了,常用的还是高级一些的API,多看看文档,遇到不明白的文档翻译翻译看看,或者搜一搜,一般就差不多了~