最近在看flutter和dart,记录一下dart和javascript/java等常见语言不同一点特性。
dart 在面向对象和java类似,但是一些异步和动态性上和javascript类似。
使用三个引号表示多行字符串
String str2 = ''' kevin
kang hello
word ''';
使用前缀r,输出原始字符串不进行转义
var s = r'kevin is \n 18'
print(s)
?? 操作符
?? 类似于js里面的|| 操作符。a??b
这个表达式的值,如果a不为空,那么为a,如果为空,那么为b
var c;
print(c ?? 20)
??=操作符
int d ;
d ??= 0;
switch 语句可以通过continue跳转到某一个特定的条件下
String str = 'c';
switch(str) {
A:
case 'java':
print('I love java');
break;
B:
case 'c':
print('I love c');
continue C;
break;
C:
case 'python':
print('I love python');
continue A;
break;
D:
case 'golang':
print('I love golang');
break;
}
dart里面,函数也是对象,函数是一等公民,可以去值可以去的任何地方。
1,函数与数字一样可以存储为变量
var func = (){print('all too well')}
2,函数与数字一样可以存储为数组的一个元素
var arr = []
Function func = (){
print('style')
}
arr.add(func)
3,函数与数字一样可以作为对象的成员变量
var obj = {}
obj['sayHello'] = () {
print('Hello ,wherever you are')
}
4, 函数与数字一样可以在使用时直接创建出来[立即执行函数]
print(42 + (){return 4;}());
5, 函数与数字一样可以被传递给另一个函数
Function weirdAdd = (n, f) { return n + f(); };
weirdAdd(42, () { return 42; }); //=>84
6, 函数与数字一样可以被另一个函数返回
Function getSayHi(){
return ()=>print('Hi sunshine is coming');
}
是不是有js内味儿了,是的。
闭包
是的,你没看错,我已经在三个地方看到闭包特性了,js、golang、还有dart。
啥是闭包,回顾一下,闭包的概念:
1,函数 与 对其状态【词法环境】的引用共同构成闭包。------->>>>> 函数可以访问外部函数的作用域。
2,闭包能够访问外部函数的变量,并且持有变量的状态
Function getPlusFunc() {
var i = 1;
return (){
print(i++);
}
}
var plusFunc = getPlusFunc();
plusFunc();
plusFunc();
plusFunc();
函数的可选参数
命名可选参数
void setInfo(String name, { int age, String gender }) {}
// 调用的时候这样调用, 可选参数顺序不一定按照定义的来
setInfo('kevin', gender: 'male', age: 20);
可选位置参数
void setInfo2(String name, [int age, String gender]) {}
// 调用的时候必须按照顺序来
setInfo2('kevin', 20, 'male');
setInfo2('kevin', 'male', 20); // 报错
class 作为声明类的关键字
1,实例化一个对象可以加new 关键字也可以不加。
2,final类型的属性,只能初始化,只读不可写。
3,默认添加getter setter函数
构造函数
普通构造函数
class Person{
string name;
int age;
}
// 有参构造函数 方法一
class Person{
String name;
int age;
Person(n, g) {
this.name = n;
this.age = g;
}
}
// 有参构造函数 方法二,语法糖
class Person{
String name;
int age;
Person(this.name, this.age);
}
// 命名构造函数
class Person {
String name;
int age;
Person.withName(this.name);
Person.withAge(this.age);
}
带final变量的构造函数
class Person {
String name;
int age;
final String gender;
// 完整构造函数, 不能在完整的构造函数给final变量赋值,但是却可以在语法糖里初始化
// Person(name, age, gender) {
// this.name = name;
// this.age = age;
// this.gender = gender;
// }
// note: 构造函数语法糖
Person(this.name, this.age, this.gender);
}
factory 构造函数 可以有返回值
…略
初始化列表
class Point{
final num x;
final num y;
// 方法一 创建对象的时候初始化
// Point(this.x, this.y);
// 方法二 构造函数调用之前,初始化final常量name
Point(num m, num n): x = m, y = n {}
Point.withAsset(this.x, this.y): assert(x > 0) {
print('In Point.withAssert(): ($x, $y)');
}
}
对象的操作符
?.
防止空指针异常
is is!
是否是指定类型
..
级联操作符
var pp = new Person();
pp..name = 'Kev'
..age = 20
..sayHi();
继承
extends 关键字,在实例化对象的时候,会先调用父类构造函数,然后子类构造函数。写法如下。
class Person{
String name;
Person(this.name);
}
class Student extends Person{
int id;
String name;
Student(this.id, this.name):super(name);
}
重要的一点:实际上在调用构造函数之前,我们已经将值赋值给了name。下面的和上面的声明是等价的。
class Person{
String name;
Person(this.name);
}
class Student extends Person{
int id;
String name;
Student(int i, String n): id = i, name = n, super(name);
}
// 执行顺序是 id = i, name = n 然后执行super(name)即是调用父类构造函数,然后再执行子类构造函数里面的方法体。
试试下面这个
class Person{
String name;
Person(this.name);
}
class Student extends Person{
int id;
String name;
Student(int i, String n): id = i, name = n, super(name) {
print(id);
print('执行方法体了');
}
}
多继承
dart 是单继承的,也就是说不能这样 class A extends B,C来写。但是实现多继承我们可以使用mixins混合, 关键字是with。
mixins类比较特殊:
1,mixins类必须继承自Object
2,mixins类不能显示的声明构造函数
class A {
void run(){
print('run a');
}
}
class B {
void run(){
print('run b');
}
}
class C {
void run() {
print('run c');
}
}
class D extends C with A, B {
}
D().run() // 执行结果为 run c // 顺序中最后一个
如果你想将mixin不能被当做常规类来使用,直接使用关键字mixin,这样这个类就不能么被实例化了。
mixin Person{
String name;
Person(this.name)
}
class Student with Person {
}
抽象类
抽象类关键字abstract,不能实例化,包含没有实现的方法,也可以包含有方法体的方法。继承抽象类,必须实现其抽象方法。
== 接口 ==
dart里面接口比较特殊,接口就是类,实现一个接口,使用关键字implements即可。大多数情况下,我们使用抽象类来作为接口,因为抽象类的抽象方法没有方法体。
操作符重写必须在类里面
oid main() {
var p1 = new Person(20);
var p2 = new Person(18);
print(p1 > p2);
print(p2['age']);
}
// note: 操作符重写必须在类里面
class Person{
int age;
Person(this.age);
// 尝试重写<> []
// 重写 >
// 为什么只有一个参数,咱们执行p1 > p2的时候,p2是参数,p1是调用者
bool operator > (Person p) {
return this.age > p.age;
}
// 重写[] 传入字符串 获取年龄
int operator [] (String age) {
return this.age;
}
}
… to be continued