基础类型 / 高级类型
最后更新于:2022-04-02 02:15:52
[TOC]
## 变量
```
var name = 'Bob'; //类型推导出 string 类型
String name = 'Bob'; //显示声明
var v1=1;
var v2="hello";
var v3=3.3;
var v4=true;
var v5=[1, 2, 3];
const c1=1;
const c2="hello";
const c3=3.3;
const c4=true;
const c5 = [1, 2, 3];
```
## 默认值
未初始化的变量默认值是 null,数字也是null,因为一切皆对象
```
int lineCount ;
assert(lineCount == null);
```
## Number
int
* 整数值不大于64位
* 值的范围从 -263 到 263 - 1
float
* 64位(双精度)浮点数
方法
* abs(), ceil(), 和 floor()
```
//生成整数
var x = 1;
var hex = 0xDEADBEEF;
//浮点数
var y = 1.1;
var exponents = 1.42e5;
//从 Dart 2.1 int 必要时会转为 float
double z = 1; // 相当于 double z = 1.0.
```
### 位运算
```
assert((3 << 1) == 6); // 0011 << 1 == 0110
assert((3 >> 1) == 1); // 0011 >> 1 == 0001
assert((3 | 4) == 7); // 0011 | 0100 == 0111
```
### 字符串,为数字相互转换
```
// String -> int
var one = int.parse('1');
assert(one == 1);
// String -> double
var onePointOne = double.parse('1.1');
assert(onePointOne == 1.1);
// int -> String
String oneAsString = 1.toString();
assert(oneAsString == '1');
// double -> String
String piAsString = 3.14159.toStringAsFixed(2);
assert(piAsString == '3.14');
```
## String
UTF-16 单元序列。 字符串通过单引号或者双引号创建
```
var s1 = 'Single quotes work well for string literals.';
var s2 = "Double quotes work just as well.";
var s3="""
hello
word
""";
var s4 ="hello "+"word";
var s = r"hello \n word"; // \b 不转义
```
### ${expression} 嵌入字符串
```
var a ="hello";
print('${a} word'); // hello word
print("${a} word"); // hello word
```
## Boolean
不同类型检查 boo 的方法
```
// 检查空字符串。
var fullName = '';
assert(fullName.isEmpty);
// 检查 0 值。
var hitPoints = 0;
assert(hitPoints <= 0);
// 检查 null 值。
var unicorn;
assert(unicorn == null);
// 检查 NaN 。
var iMeantToDoThis = 0 / 0;
assert(iMeantToDoThis.isNaN);
```
## List 数组
```
var a= [1, 2, 3];
//等效
List a =[1,2,3];
//长度
a.length
```
常量赋值
```
var constantList = const [1, 2, 3];
// constantList[1] = 1; // 取消注释会引起错误。
constantList=[1,3,3]; //可以整体替换
```
## Set 唯一且无序的值
方法
* add(), addAll()
属性
* .length
实例
```
var a ={};
a.add("a");
a.addAll({"b","c"});
a.remove("b");
// a.clear(); // 清空所有
print(a.contains("c")); // true 是否包含c
print(a.first);//a
```
```
var halogens = {'fluorine', 'chlorine', 'bromine', 'iodine', 'astatine'};
//等效
Set halogens1= {'fluorine', 'chlorine', 'bromine', 'iodine', 'astatine'};
```
### 创建空集
```
var names = {};
// Set names = {}; // 这样也是可以的。
// var names = {}; // 这样会创建一个 Map ,而不是 Set 。
```
### 设置 编译时常量
```
final constantSet = const {
'fluorine',
'chlorine',
'bromine',
'iodine',
'astatine',
};
// constantSet.add('helium'); // Uncommenting this causes an error.
```
## Map k-v 类型
```
//类型推导为 Map
var gifts = {
// Key: Value
'first': 'partridge',
'second': 'turtledoves',
'fifth': 'golden rings'
};
//类型推导为 Map
var nobleGases = {
2: 'helium',
10: 'neon',
18: 'argon',
};
final constantMap = const {
2: 'helium',
10: 'neon',
18: 'argon',
};
```
基本操作
```
//赋值
gifts['first'] = 'calling birds'; // Add a key-value pair
//取值
assert(gifts['first'] == 'partridge');
```
## Rune
Rune 用来表示字符串中的 UTF-32 编码字符,由于 Dart 字符串是一系列 UTF-16 编码单元, 因此要在字符串中表示32位 Unicode 值需要特殊语法支持
```
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));
}
//output
👏
[55357, 56399]
[128079]
♥ 😅 😎 👻 🖖 👍
```
## 函数
函数也是对象
```
add(n) {
return n+1;
}
int add2( int n) {
return n+1;
}
add3(int n)=>n+1; //默认以 return 返回
main() {
print(add(2)); // 3
print(add2(2));// 3
print(add3(2));// 3
}
```
### 可选参数
命名参数或者位置参数,但一个参数只能选择其中一种方式修饰
#### 命名可选参数
```
echo({int age,String name}){
print(age);
print(name);
}
main() {
echo(name:"cc" );// 22 null
}
```
#### 位置可选参数
```
echo(String name,[int age]){
print(name);
print(age);
}
main() {
echo("cc");//cc null
}
```
### 默认参数值
命名可选参数
```
echo({int age=22,String name="cc"}){
print(age);
print(name);
}
main() {
echo(name: "dd");// 22 dd
}
```
位置可选参数
```
echo(String name,[int age=12]){
print(name);
print(age);
}
main() {
echo("cc");//cc 12
}
```
list 或map 天界默认值
```
void doStuff(
{List list = const [1, 2, 3],
Map gifts = const {
'first': 'paper',
'second': 'cotton',
'third': 'leather'
}}) {
print('list: $list');
print('gifts: $gifts');
}
main() {
doStuff();
}
```
### 函数作为参数传入
```
void printElement(int element) {
print(element);
}
var list = [1, 2, 3];
// 将 printElement 函数作为参数传递。
list.forEach(printElement);
```
### 匿名函数
```
var a=["a","b","c"];
a.forEach((item){
print('${a.indexOf(item)}: ${item}');
});
//等价
list.forEach((item) => print('${list.indexOf(item)}: $item'));
//output
0: a
1: b
2: c
```
## 运算符
```
// 类型判定运算符
print("1" is String); //true
if (emp is Person) {
// Type check
emp.firstName = 'Bob';
}
// 缩写
(emp as Person).firstName = 'Bob'; //如果 emp 为null 为报异常
//关系运算符
assert(2 + 3 == 5);
assert(2 - 3 == -1);
assert(2 * 3 == 6);
assert(5 / 2 == 2.5); // 结果是双浮点型
assert(5 ~/ 2 == 2); // 结果是整型
assert(5 % 2 == 1); // 余数
b ??= value; // 如果b为空时,将变量赋值给b,否则,b的值保持不变。
// 条件表达式
var visibility = isPublic ? 'public' : 'private';
```
### 级联运算符
实现对同一个对像进行一系列的操
还可以访问同一对象上的字段属性
```
querySelector('#confirm') // 获取对象。
..text = 'Confirm' // 调用成员变量。
..classes.add('important')
..onClick.listen((e) => window.alert('Confirmed!'));
//等价于
var button = querySelector('#confirm');
button.text = 'Confirm';
button.classes.add('important');
button.onClick.listen((e) => window.alert('Confirmed!'));
```
## 控制流程语句
大
### if
```
if (isRaining()) {
you.bringRainCoat();
} else if (isSnowing()) {
you.wearJacket();
} else {
car.putTopDown();
}
```
### for 循环
```
for (var i = 0; i < 5; i++) {
...
}
```
迭代
```
var collection = [0, 1, 2];
for (var x in collection) {
print(x); // 0 1 2
}
```
### switch
```
var command = 'OPEN';
switch (command) {
case 'CLOSED':
executeClosed();
break;
case 'PENDING':
executePending();
break;
default:
executeUnknown();
}
```
## 异常
```
throw FormatException('Expected at least 1 section');
throw 'Out of llamas!';
// 抛出任意的对象
try {
throw FormatException("1111");
// throw "222";
} on Exception catch (e) {
// 其他任何异常
print('Unknown exception: $e'); //1111
} catch (e) {
// 没有指定的类型,处理所有异常
print('Something really unknown: $e'); // 222
}
```
### 重新抛出异常
```
try {
dynamic foo = true;
print(foo++); // Runtime error
} catch (e) {
print('misbehave() partially handled ${e.runtimeType}.');
rethrow; // Allow callers to see the exception.
}
```
### finally
```
try {
throw "222";
} catch (e) {
print('Something really unknown: $e');
} finally{
print("end"); //end
}
//output
// Something really unknown: 222
//end
```
## 类
```
class person {
String name;
}
void main() {
var a = new person(); //等效 var a = asd();
print(a.runtimeType); // person
获取运行时类型
print(a?.name = "cc"); //如果name 为null 则赋值 cc
}
```
> 在 Dart 2 中 new 关键字变成了可选的。
### 构造函数
```
class person {
String name;
int age=0;
person(String name,this.age){ //this.age 为语法糖
this.name=name;
}
}
void main() {
var a = person("cc",23);
print(a.name); // cc
print(a.age); // 23
}
```
> 构造函数不能够被继承
### Getter 和 Setter
```
class person {
String name;
num _age = 0;
person(name, this._age) {
this.name = name;
}
num get age1 => _age + 1;
num get age2 {
return _age + 1;
}
set age3 (num a)=> _age=_age-10;
}
void main() {
var a = person("cc", 23);
print(a.age1); // 24
print(a.age2); // 24
a.age3=123;
print(a.age1); // 14
}
```
### 抽象方法 / 抽象类
实例方法, getter, 和 setter 方法可以是抽象的, 只定义接口不进行实现,而是留给其他类去实现。 抽象方法只存在于 抽象类 中。
```
abstract class Doer {
// 定义实例变量和方法 ...
void doSomething(); // 定义一个抽象方法。
}
class EffectiveDoer extends Doer {
void doSomething() {
// 提供方法实现,所以这里的方法就不是抽象方法了...
}
}
```
### 扩展类(继承)
使用 extends 关键字来创建子类, 使用 super 关键字来引用父类:
```
class Television {
void turnOn() {
_illuminateDisplay();
_activateIrSensor();
}
// ···
}
class SmartTelevision extends Television {
void turnOn() {
super.turnOn();
_bootNetworkInterface();
_initializeMemory();
_upgradeApps();
}
// ···
}
```
### 重写类成员
```
class SmartTelevision extends Television {
@override
void turnOn() {...}
// ···
}
```
### noSuchMethod() 调用不存在的方法触发
```
class A {
// 如果不重写 noSuchMethod,访问
// 不存在的实例变量时会导致 NoSuchMethodError 错误。
@override
void noSuchMethod(Invocation invocation) {
print('You tried to use a non-existent member: ' +
'${invocation.memberName}');
}
}
```
### 类变量和方法
#### 静态变量
静态变量只到它们被使用的时候才会初始化。
```
class Queue {
static const initialCapacity = 16;
// ···
}
void main() {
assert(Queue.initialCapacity == 16);
}
```
#### 静态方法
静态方法(类方法)不能在实例上使用,因此它们不能访问 this
```
class person {
static echo(String name) {
print('hello ${name}');
}
}
void main() {
person.echo('cc');
}
```
### call() 方法
```
class WannabeFunction {
call(String a, String b, String c) => '$a $b $c!';
}
main() {
var wf = new WannabeFunction();
var out = wf("Hi","there,","gang");
print('$out'); // Hi there, gang!
}
```
### 元数据
#### @deprecated 被弃用的
若某类或某方法加上该注解之后,表示此方法或类不再建议使用,调用时也会出现删除线
```
class Television {
@deprecated
void activate(){
turnOn();
}
}
```
#### @override重写
#### @proxy 代理
#### @required 来标记一个参数
* 告诉编译器这个参数必须要传值
* 告诉读代码的人,这个参数必须要填写
## 泛型
```
abstract class ObjectCache {
Object getByKey(String key);
void setByKey(String key, Object value);
}
abstract class StringCache {
String getByKey(String key);
void setByKey(String key, String value);
}
// 泛型实现
abstract class Cache {
T getByKey(String key);
void setByKey(String key, T value);
}
```
### 限制泛型类型
```
class Foo {
// Implementation goes here...
String toString() => "Instance of 'Foo<$T>'";
}
class Extender extends SomeBaseClass {...}
// 可以使用 SomeBaseClass 或其任意子类作为通用参数:
var someBaseClassFoo = Foo();
var extenderFoo = Foo();
```
## 枚举类型
```
enum Color { red, green, blue }
//枚举都有 getter 犯法
assert(Color.green.index == 1);
//枚举的 values 常量
List colors = Color.values;
assert(colors[2] == Color.blue);
var aColor = Color.blue;
switch (aColor) {
case Color.red:
print('Red as roses!');
break;
case Color.green:
print('Green as grass!');
break;
default: // 没有这个,会看到一个警告。
print(aColor); // 'Color.blue'
}
```
## typedef 声明一种类型
```
typedef int Compare(int a, int b);
int sort(int a, int b) => a - b;
main() {
print(sort is Compare); //true
}
```
';