之后使用的dart都是2.16.2
main函数
hello world
void main(List<String> args) {
print("Hello world!!!");
}
main函数是入口,语句结束要加;
声明变量
明确的声明
类型+变量名
String name = "Steven";
类型推导
关键字var同swift里的var,
final同swift里的let,
const同oc里的const上述关键字一旦确认类型不可改变,
dynamic任意类型,确认类型后还可以更改类型,调用方法时,编译不会报错,存在隐患
Object任意类型,确认类型后还可以更改类型,调用方法时,编译会报错
数据类型
int,num,double,bool
其中String的使用同Python,进行拼接则使用${},如果只是变量,则可省略{}
String->num int.parse(变量) double.parse(变量)
str.isEmpty 是否是空字符串
num.isNaN 是否为空num
num->String 变量.toString()
集合
list同数组,set同集合,map同字典
枚举
关键词enum,使用固定的值,类型安全
void main(List<String> args) {
final s = sex.man;
switch (s) {
case sex.man:
print("man");
break;
case sex.woman:
print("woman");
break;
}
print(sex.values);
print(sex.man.index);
}
enum sex { man, woman }
函数
返回类型(可省略,但不推荐) + 函数名 + (必选参数 + [位置可选参数]或{命名可选参数}) { 函数体 }
eg:
void sayHello1(String name, [int age = 10]) {
print("$name : $age");
}
void sayHello2(String name, {int age = 12}) {
print("$name : $age");
}
函数作为参数
使用Function修饰,但不建议,建议直接写函数表达式
eg:
void main(List<String> args) {
//匿名函数
test((a, b) {
print(a + b);
return a + b;
});
}
typedef Calculate = int Function(int a, int b);
void test(Calculate cal) {
var res = cal(2, 3);
print(res);
}
函数作为返回值
eg:
void main(List<String> args) {
//d1是Calculate类型的函数,需要传入a,b两个参数
var d1 = demo();
print(d1(3, 5));
}
typedef Calculate = int Function(int a, int b);
//返回类型Calculate,返回了一个匿名函数
Calculate demo() {
return ((a, b) {
return a * b;
});
}
箭头函数
函数体只有一行代码
() => {print("这是箭头函数")};{}可以省略
匿名函数
无函数名 (参数) { 函数体},参见上面注释
特殊运算符
赋值运算符
??=当赋值的变量不为空时不赋值,当变量为空时才执行
??同Swift,符号前面的值不为空时使用前面的值,为空时使用后面的值
级联运算符
..对一个对象的操作可以通过级联运算符连接,语句结束加;即可
循环
for,for in同oc,switf
类的构造函数
常规的都可以,也可以通过KVC模式构造
eg:
void main(List<String> args) {
var cat = Animal.fromMap({"name": "kitty", "age": 2, "male": true});
//toString()可以省略
print(cat.toString());
var dog1 = Animal("dog", 12);
var dog2 = Animal("dog2", 15, male: true);
print(dog1);
print(dog2);
}
class Animal {
String? name;
int? age;
bool? male;
// 语法糖 初始化列表
Animal(this.name, this.age, {male}) : this.male = male ?? false;
Animal.fromMap(Map<String, dynamic> map, {String}) {
this.name = map["name"];
this.age = map["age"];
this.male = map["male"];
}
@override
String toString() {
return "name:$name,age:$age,male:$male";
}
}
重定向构造函数
关键字_internal
void main(List<String> args) {
var s = Student("Bob");
print(s.age);
}
class Student {
String name;
int age;
Student(String name) : this._internal(name, 20);
Student._internal(this.name, this.age);
}
常量构造函数
void main(List<String> args) {
const s1 = Student("name");
const s2 = Student("name");
//对比得出s1与s2指向同一块内存,是一个对象
print(identical(s1, s2));
}
class Student {
final String name;
const Student(this.name);
}
工厂构造函数
区别:普通的构造函数会返回一个创建的对象,工厂构造函数可以手动返回一个对象。
void main(List<String> args) {
final s1 = Student.withName("bob");
final s2 = Student.withName("bob");
final s3 = Student.withAge("20");
final s4 = Student.withAge("20");
//对比得出s1与s2相等
print(identical(s1, s2));
//对比得出s3与s4相等
print(identical(s3, s4));
}
class Student {
String name;
String age;
static final Map<String, Student> _nameCache = <String, Student>{};
static final Map<String, Student> _ageCache = <String, Student>{};
factory Student.withName(String name) {
//putIfAbsent.如果存在[key],则会返回它的值。如果不存在,就会调用后面的函数,生成新值,然后插入,并返回该值。
return _nameCache.putIfAbsent(name, () => Student(name, "10"));
}
factory Student.withAge(String age) {
return _ageCache.putIfAbsent(age, () => Student("name", age));
}
Student(this.name, this.age);
}
setter和getter
void main(List<String> args) {
var c = Cat();
c.setName = "cat";
print(c.getName);
}
class Cat {
late String name;
set setName(String name) => this.name = name;
/*set setName(String name) {
this.name = name;
}*/
String get getName => this.name;
/*String get getName {
return this.name;
}*/
}
继承
关键字extends,只支持单继承
void main(List<String> args) {
var c = Cat(20, "kitty");
}
class Animal {
String name;
Animal(this.name);
}
class Cat extends Animal {
int age;
Cat(this.age, String name) : super(name);
}
抽象类
关键字abstract
普通类中的方法必须实现,抽象类中的方法可以不实现;
继承抽象类后,必须实现抽象类的抽象方法
正常情况下抽象类不能实例化(new 类()),除非加工厂构造函数
external:将方法的声明和方法的实现分离,通过@patch实现方法
隐式接口
关键字implements
将一个类作为接口使用时,则实现这个接口的类必须实现这个接口中的所有方法
class Cat {
void running() {}
}
class Dog {
void jumping() {}
}
class Animal implements Cat, Dog {
@override
void running() {
// TODO: implement running
}
@override
void jumping() {
// TODO: implement jumping
}
}
注:继承可以调用super,实现不可以
继承抽象类和implements区别:
- 如果要福永抽象类里面的方法,并且要用抽象类方法约束子类的话就继承抽象类
- 如果只是把抽象类当标准的话就使用
implements实现抽象类
mixin混入
关键词mixin定义,with混入.优先级:重写 > 混入 > 继承
mixin Cat {
void running() {}
}
mixin Dog {
void jumping() {}
}
class Animal with Cat, Dog {}
- 作为mixins的类只能继承自Object,不能继承其他类
- 作为mixins的类不能有构造函数
- 一个类可以mixins多个mixins类
- Mixins不是继承,也不是接口,是一个全新的特性。
class M extends N with A,B(一个类M,继承自类N,混入A,B),其中N,A,B有同一个方法,则使用最后一个混入的类B
类属性和类方法
- 使用
static关键字来实现类级别的变量和函数 - 静态方法不能访问非静态成员,非静态方法可以访问静态成员
void main(List<String> args) {
var c = Cat();
c.name = "mimi";
Cat.kind = "animal";
c.running();
Cat.living();
}
class Cat {
// 成员属性
late String name;
// 类属性
static String? kind;
// 成员方法
void running() {
print("running");
}
// 类方法
static void living() {
print("living");
}
}
extension扩展
extension 扩展名 on 扩展的类 { //扩展内容}
泛型
一般用T作为关键字,作用:解决类,接口,方法等的复用性(冗余),以及对不特定数据类型的支持(校验)
ok,dart的语法基本就到这里了,异步线程啥的要到后面Flutter里再学了。
