(原创)
很多人都玩过“找别扭”这款游戏,下面大家一起来看看 Dart 有何与众不同。在讨论Dart 之前,还是按照惯例,先做一个“计划”,需要了解的东西划分一下重点,然后再一个个看。
划分重点
- 数据类型 & 变量
- 函数
- 控制流
- 类
- 库
- 编程范式
- 编译 & 运行
数据类型 & 变量
一切皆对象
(有没有很像JS?)
在 Dart 中,一切变量都是引用的对象,每个对象都是一个类型的实例,因此,所有的类型都是 对象类型。
继承
如上所述,一切皆对象,而万物皆有根,此根在dart 中是 Object 类型,所有类型都是 Object 类型,专业一点说,叫都继承自 Ojbect 类型。不仅包括了函数,也包括了 int 这种可能被惯性意识认为的“基本类型”
Inheritance
Object > num > int
在很多语言中,对象类型变量默认值是null,在dart 中也是如此,而且所有类型的默认值都是 null。
一些常见类型
- int
- double
- String
- bool
- List
- Set
- Map
- Runes
- Symbol
关于类型的详细说明不在这里赘述, 可以参考 https://www.dartcn.com/guides/language/language-tour
API 文档:
https://api.flutter.dev/flutter/dart-core/dart-core-library.html
常量
常量可以通过用 Final 和 Const 来修饰变量
- const: 在编译时初始化,此后不可修改,若初始化未赋值,编译不通过
- final: 在第一次赋值后不可修改
变量初始化
-
字面量初始化
以上几种类型都支持字面量初始化
例如通过字面量初始化一个String类型对象:
String stringInstance = "abc";
-
通过构造函数初始化
由于一切对象都属于类,是类就有构造函数,因此也可以通过构造函数初始化
String i = String.fromCharCode(69);
作用域
Dart 使用词法作用域(也称为静态作用域),即变量的作用域在定义时确定。
作用域范围由变量所处代码块(大括号)的层级决定,层级越深,作用域越小,层级越浅,作用域越大。
不被任何代码块包含的变量通常称为顶层变量,它们的作用域最大
全局变量
在dart 中,似乎并没有看到像C语言一样的全局变量,多个文件可以访问同一个变量(同一块内存)。那如何实现呢?
这里有个关键点: “多个文件引用同一个dart文件,只会执行一次。变量是共享的。”
所以,在一个文件中定义全局的一些变量,在其它文件中引入使用就好了。
私有变量
在变量前面加前缀 _ 就是私有变量(仅Library 内部可见)
静态变量
在类中生命的成员变脸添加 Static 关键字,为静态成员,静态成员属于类本身(类对象本身),所有该类对象共有一份存储,文件外部可通过类直接访问。
Class People {
// 声明
static String peopleCount = "60亿";
}
再来看看使用:
print(People.peopleCount);
强类型
可以指明类型
//例如:
int a = 1;
编译时,会进行类型检查,因此,是类型安全的。如果对 int 类型 赋予 double 类型的值,也会编译报错: 如下:
//例如:
int a = 1.0;
得到如下编译错误:
Error compiling to JavaScript:
main.dart:2:11:
Error: A value of type 'double' can't be assigned to a variable of type 'int'.
int a = 1.0;
^
Error: Compilation failed.
类型推断
我们也可以不指明类型声明变量,如:
var a = 1;
看起来像极了JS 的“弱类型”, 但它并不是真的弱类型,因为与 js 不同的是,dart 会在编译的时候进行类型推断和安全校验,所以它还是类型安全的。
函数
基本写法
可以像像C函数一样
int getSum(int a, int b) {
return a + b;
}
函数体内单行实现也可以这样写:
int getSum(int a, int b) => return a + b;
参数特殊处理
甚至可以跟JS一样,省略参数:
int getSum(a, b) {
return a + b;
}
可选参数,花括号 {} 或中括号 [] 中的参数是可选的:
int getSum(a, b, {c}) {
return a + b + c;
}
//也可以是
int getSum(a, b, [c]) {
return a + b + c;
}
参数默认值:
//像JS一样,设置参数c默认值,如果C没有传,默认设置为1
int getSum(a, b, {c = 1}) {
return a + b + c;
}
函数也是对象,也可以作为参数:
void main() {
var sum = caculateSum(getSum);
print(sum); //console: 4
}
int getSum(a, int b) {
return a + b;
}
int caculateSum(Function getSumFunc){
return getSumFunc(1, 2);
}
闭包
闭包特点, 引述 https://www.jianshu.com/p/ec2cd19234f9 的归纳:
- 闭包是一个方法(对象)
- 闭包定义在其他方法内部
- 闭包能够访问外部方法内的局部变量,并持有其状态(这是闭包最大的作用,可以通过闭包的方式,将其暴露出去,提供给外部访问)
示例:
//闭包的包裹函数, 闭包在函数内声明, 生成并返回一个闭包
Function makeA_BiBao () {
int count = 0;
Function woShiBiBao = () => {
print(count ++)
};
return woShiBiBao;
}
void main() {
Function woShiBiBao = makeA_BiBao(); //生成闭包
//调用5次闭包
for (int index = 0; index < 5; index ++) {
woShiBiBao();
}
}
console 输出:
0
1
2
3
4
流程控制
条件判断
if-else
if (true) {
print("true");
} else {
print("false");
}
switch 和 case
(这里比较的值不仅限于枚举、整数,还可以是其他对象,如字符串,或者编译时常量,使用 == 进行比较,⚠️:“比较的对象必须都是同一个类的实例(并且不可以是子类), 类必须没有对 == 重写”)
照搬 “ https://www.dartcn.com/guides/language/language-tour#控制流程语句 ”
中的例子:
var command = 'OPEN';
switch (command) {
case 'CLOSED':
executeClosed();
break;
case 'PENDING':
executePending();
break;
case 'APPROVED':
executeApproved();
break;
case 'DENIED':
executeDenied();
break;
case 'OPEN':
executeOpen();
break;
default:
executeUnknown();
}
循环
经典for循环
for (int index = 0; index < 5; index ++) {
print(index); // 0 1 2 3 4
}
for-each
[8,9].forEach((int value)=> print(value)); //8 9
for-in
for (var x in [8,9]) {
print(x); // 8 9
}
while
int i = 0;
while (i < 5) {
i++;
print(i);
}
do-while
int i = 0;
do {
print(i);
i ++;
} while (i < 5);
break 和 continue
(没啥特别)
断言 assert
退出当前流程,仅在debug模式中生效
assert(text != null); //确认值不为空,如果为空则终端机程序流程
异常
当出现了异常,程序不会继续顺序执行,而跳转到异常处理对应的分支执行。
- 抛出异常
Dart 提供了 Exception 和 Error 类型, 以及一些子类型。 当然也可以定义自己的异常类型。 但是,此外 Dart 程序可以抛出任何非 null 对象, 不仅限 Exception 和 Error 对象。
throw FormatException('Expected at least 1 section');
或任意非null对象
throw "this is a exception";
- 捕获异常
- try - catch - finally, 当 try 块中发生了异常,跳转到catch中执行,不管是否有异常,最终都会执行 finally。
- 捕获语句中可以同时使用 on 和 catch ,也可以单独分开使用。 使用 on 来指定异常类型, 使用 catch 来 捕获异常对象。
catch()
函数可以指定1到2个参数, 第一个参数为抛出的异常对象, 第二个为堆栈信息 ( 一个 StackTrace 对象 )。
try {
// ···
} on Exception catch (e) {
print('Exception details:\n $e');
} catch (e, s) {
print('Exception details:\n $e');
print('Stack trace:\n $s');
} finally {
print('最终一定会执行');
}
类
类的定义
类由成员变量、构造函数、成员函数等部分组成, 如下
class Person {
static int humanCount = 5; //类变量
String name; //成员变量
//构造函数
Person(String name) {
this.name = name;
}
//成员函数
String getName(){
return this.name;
}
//类函数
static int getHumanCount() {
return humanCount;
}
}
void main() {
Person p = Person("隔壁老王"); //调用构造函数,创建Person类实例p
print(p.name); // 隔壁老王
print(p.getName()); // 隔壁老王
print(Person.getHumanCount()); // 5
}
构造函数还有多种使用方法,参考: https://www.dartcn.com/guides/language/language-tour#构造函数
抽象类
抽象类,一般不能实例化,通过定义一个工厂构造函数后可实例化
abstract class AbstractContainer {
// 定义构造函数,字段,方法...
void updateChildren(); // 抽象方法。
}
接口(隐式)
每个类(包括抽象类)都隐式的定义了一个接口,该接口包含了该类所有的实例成员(实例变量 + 实例函数)及其实现(implements)的接口【这体现了继承关系】。
接口的目的是定义,而实现交给实现接口的类,一个类可以实现1个或多个接口,如下:
// person 类。 隐式接口里面包含了 greet() 方法声明。
class Person {
// 包含在接口里,但只在当前库中可见。
final _name;
// 不包含在接口里,因为这是一个构造函数。
Person(this._name);
// 包含在接口里。
String greet(String who) => 'Hello, $who. I am $_name.';
}
// person 接口的实现。
class Impostor implements Person {
get _name => '';
String greet(String who) => 'Hi $who. Do you know who I am?';
}
实现多个接口
class Point implements Comparable, Location {...}
继承
继承没有什么特别需要说的,跟很多语言一样
class Television {
void turnOn() {
_illuminateDisplay();
_activateIrSensor();
}
// ···
}
class SmartTelevision extends Television {
void turnOn() {
super.turnOn();
_bootNetworkInterface();
_initializeMemory();
_upgradeApps();
}
// ···
}
重写运算符
C++运算符重载?
class Vector {
final int x, y;
Vector(this.x, this.y);
//重写+运算
Vector operator +(Vector v) => Vector(x + v.x, y + v.y);
//重写-运算
Vector operator -(Vector v) => Vector(x - v.x, y - v.y);
}
枚举类
enum Color { red, green, blue }
每个枚举值都有一个获取索引的方法.
assert(Color.red.index == 0);
assert(Color.green.index == 1);
assert(Color.blue.index == 2);
标签:文件,语言,int,dart,类型,初识,print,Dart
From: https://www.cnblogs.com/clark1990/p/17379782.html