Dart笔记一(基础语法)

1.Dart独特语法(相比于Java,C++,js)

1.1表达式

空安全

//表示允许为null
String? name

//如果fooList不为空,调用下标1的元素,否则为null
fooList?[1]

//如果foo不为空,调用foo的属性bar,否则 foo?.bar的值为null
foo?.bar

修饰符 late

  • 声明一个非空变量,但不在声明时初始化。

  • 延迟初始化一个变量。

//懒加载初始化,直到temperature被调用,函数readThermometer()才会被调用,否则不调用
late String temperature = readThermometer(); 

运行时类型检查运算符 as   is    is!

//类型推断
(employee as Person).firstName = 'Bob';

if (employee is Person) {
  // Type check
  employee.firstName = 'Bob';
}

运算符 ??=

// 赋值给a
a = value;
// b为null时,需要使用??= ,否则b保持不变
b ??= value;

运算符 ??

//name如果不是null,则返回name的值,否则返回'Guest'
String playerName(String? name) => name ?? 'Guest';

级联表示法

//下面的..等效于 paint.
var paint = Paint()
  ..color = Colors.black
  ..strokeCap = StrokeCap.round
  ..strokeWidth = 5.0;

//在第一个级联的前面加问号,相当于后面所有都有了判空的功能
querySelector('#confirm') // 获取对象
  ?..text = 'Confirm' // 如果对象非空,则赋值
  ..classes.add('important')
  ..onClick.listen((e) => window.alert('Confirmed!'))
  ..scrollIntoView();

//嵌套级联
final addressBook = (AddressBookBuilder()
      ..name = 'jenny'
      ..email = 'jenny@example.com'
      ..phone = (PhoneNumberBuilder()
            ..number = '415-555-0100'
            ..label = 'home')
          .build())
    .build();

文档注释

注解

库的导入

//两包里都有Element类,防止混淆
import 'package:lib1/lib1.dart';
import 'package:lib2/lib2.dart' as lib2;

//使用lib1中的Element
Element element1 = Element();

//使用lib2中的Element
lib2.Element element2 = lib2.Element();

//只导入foo对象
import 'package:lib1/lib1.dart' show foo;

//除了foo都导入
import 'package:lib2/lib2.dart' hide foo;


/** 懒加载库,只有用到的时候才导入
   减少网络应用程序的初始启动时间。
   执行 A/B 测试——例如,尝试算法的替代实现。
   加载很少使用的功能,例如可选屏幕和对话框。
*/
import 'package:greetings/hello.dart' deferred as hello;

Future<void> greet() async {
  //loadLibrary()可多次使用,只加载一次
  await hello.loadLibrary();
  hello.printGreeting();
}

1.2类型 

Dart比java更加面向对象,基本类型,函数皆为对象。

新奇的基本类型

  • Runes (Runes; often replaced by the characters API)

处理表情符号的用法,过于抽象,不想解释

标识符用法

  • The value null (Null)

空类型

记录类型


//record表达式是以逗号分隔的命名或位置字段列表,括在括号中:
var record = ('first', a: 2, b: true, 'last');

//定义参数类型和返回类型
(int, int) swap((int, int) record) {
  var (a, b) = record;
  return (b, a);
}

// record类型的变量声明
(String, int) record;

// 用record表达式初始化
record = ('A string', 123);


var record = ('first', a: 2, b: true, 'last');

// $<position>来获取指定位置元素
print(record.$1); // 打印 'first'
print(record.a); // 打印 2
print(record.b); // 打印 true
print(record.$2); // 打印 'last'

(num, Object) pair = (42, 'a');

var first = pair.$1; // Static type `num`, runtime type `int`.
var second = pair.$2; // Static type `Object`, runtime type `String`.

/*
  相等性
*/

(int x, int y, int z) point = (1, 2, 3);
(int r, int g, int b) color = (1, 2, 3);

print(point == color); // 打印 'true'.

({int x, int y, int z}) point = (x: 1, y: 2, z: 3);
({int r, int g, int b}) color = (r: 1, g: 2, b: 3);

print(point == color); // 打印 'false'.类型不对应

/*
  多重返回值
*/

// 用record返回多重值
(String name, int age) userInfo(Map<String, dynamic> json) {
return (json['name'] as String, json['age'] as int);
}

// 使用指定字段的record进行解构

final json = <String, dynamic>{
'name': 'Dash',
'age': 10,
'color': 'blue',
};


var (name, age) = userInfo(json);

/* 等效于
  var info = userInfo(json);
  var name = info.$1;
  var age  = info.$2;
*/

({String name, int age}) userInfo(Map<String, dynamic> json)

// 用命名字段的record解构
final (:name, :age) = userInfo(json);

集合

//通过...将一个集合插入,此时list2元素有4个
var list = [1, 2, 3];
var list2 = [0, ...list];
assert(list2.length == 4);

//list如果可能为null,可用...?预防
var list2 = [0, ...?list];
assert(list2.length == 1);

//创建的值可能是三个也可能是四个,根据if来判断是否创建第四个
var nav = ['Home', 'Furniture', 'Plants', if (promoActive) 'Outlet'];

var nav = ['Home', 'Furniture', 'Plants', if (login case 'Manager') 'Inventory'];

//for创建
var listOfInts = [1, 2, 3];
var listOfStrings = ['#0', for (var i in listOfInts) '#$i'];
assert(listOfStrings[1] == '#1');

var [a, b, ..., c, d] = [1, 2, 3, 4, 5, 6, 7];
// Prints "1 2 6 7".
print('$a $b $c $d');

//rest表示剩余元素集合
var [a, b, ...rest, c, d] = [1, 2, 3, 4, 5, 6, 7];
// Prints "1 2 [3, 4, 5] 6 7".
print('$a $b $rest $c $d');

函数

/// 设置参数默认值{}
void enableFlags({bool bold = false, bool hidden = false}) {...}

// bold值是true,hidden默认为false
enableFlags(bold: true);

//required表示参数必须提供,否则报错
const Scrollbar({super.key, required Widget child});

//用[]设置可选参数,如果不提供一个默认的值,则它们类型必须是可空且值为空
String say(String from, String msg, [String? device]) {
  var result = '$from says $msg';
  if (device != null) {
    result = '$result with a $device';
  }
  return result;
}

//如果不设置可为空,必须初始化
String say(String from, String msg, [String device = 'carrier pigeon']) {
  var result = '$from says $msg with a $device';
  return result;
}

assert(say('Bob', 'Howdy') == 'Bob says Howdy with a carrier pigeon');


//将函数作为参数
void printElement(int element) {
  print(element);
}

var list = [1, 2, 3];

// Pass printElement as a parameter.
list.forEach(printElement);

//将函数传给变量
var loudify = (msg) => '!!! ${msg.toUpperCase()} !!!';
assert(loudify('hello') == '!!! HELLO !!!');

//匿名方法
const list = ['apples', 'bananas', 'oranges'];
list
    .map((item) => item.toUpperCase())
    .forEach((item) => print('$item: ${item.length}'));

/*词法闭包
捕获外部变量:闭包可以捕获并保持其外部作用域(即词法作用域)中的变量。
延长变量生命周期:闭包能够延长被捕获变量的生命周期,使这些变量在闭包存在期间不会被回收。
函数与环境绑定:闭包是函数和它的词法环境的组合,闭包中保存的变量是函数定义时的变量,而不是函数调用时的变量。
*/

/// 高阶函数(作用域在顶层),实现闭包
Function makeAdder(int addBy) {
  return (int i) => addBy + i;
}

void main() {
  // 创建一个加2的函数
  var add2 = makeAdder(2);

  // 创建一个加4的函数
  var add4 = makeAdder(4);

  assert(add2(3) == 5);
  assert(add4(3) == 7);
}

//没有返回值的函数默认返回null
foo() {}
assert(foo() == null);

/* 生成器:延迟生成一系列值,
同步生成器: 返回一个Iterable对象.
异步生成器: 返回一个Stream对象.
*/

///要实现同步生成器函数,请将函数体标记为sync*,并使用yield语句传递值:
Iterable<int> naturalsTo(int n) sync* {
  int k = 0;
  while (k < n) yield k++;
}


//要实现异步生成器函数,请将函数体标记为async*,并使用yield语句传递值:
Stream<int> asynchronousNaturalsTo(int n) async* {
  int k = 0;
  while (k < n) yield k++;
}

//通过使用yield*来提高递归生成器的性能:
Iterable<int> naturalsDownFrom(int n) sync* {
  if (n > 0) {
    yield n;
    yield* naturalsDownFrom(n - 1);
  }
}

//声明与结构体实现分离的做法
external void someFunc(int i);

控制流


//词法闭包捕获下标
var callbacks = [];
for (var i = 0; i < 2; i++) {
  callbacks.add(() => print(i));
}

for (final c in callbacks) {//输出0,1
  c();
}


//遍历可迭代集合(list和set)
for (final candidate in candidates) {
  candidate.interview();
}

//处理从iterable中获取的值
for (final Candidate(:name, :yearsExperience) in candidates) {
  print('$name has $yearsExperience of experience.');
}

//可迭代集合有forEach方法
var collection = [1, 2, 3];
collection.forEach(print); // 1 2 3


for (int i = 0; i < candidates.length; i++) {
  var candidate = candidates[i];
  if (candidate.yearsExperience < 5) {
    continue;
  }
  candidate.interview();
}

//可迭代集合能更简便替换上面这段
candidates
    .where((c) => c.yearsExperience >= 5)
    .forEach((c) => c.interview());

//switch case重写
// Where slash, star, comma, semicolon, etc., are constant variables...
switch (charCode) {
  case slash || star || plus || minus: // Logical-or pattern
    token = operator(charCode);
  case comma || semicolon: // Logical-or pattern
    token = punctuation(charCode);
  case >= digit0 && <= digit9: // Relational and logical-and patterns
    token = number();
  default:
    throw FormatException('Invalid');
}

//改写为表达式
token = switch (charCode) {
  slash || star || plus || minus => operator(charCode),
  comma || semicolon => punctuation(charCode),
  >= digit0 && <= digit9 => number(),
  _ => throw FormatException('Invalid')
};

/*
类的匹配
*/
sealed class Shape {}

class Square implements Shape {
  final double length;
  Square(this.length);
}

class Circle implements Shape {
  final double radius;
  Circle(this.radius);
}

double calculateArea(Shape shape) => switch (shape) {
      Square(length: var l) => l * l,
      Circle(radius: var r) => math.pi * r * r
    };

//Guard clause:通过when关键字满足一些特定条件
// Switch statement:
switch (something) {
  case somePattern when some || boolean || expression:
    //             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Guard clause.
    body;
}

// Switch expression:
var value = switch (something) {
  somePattern when some || boolean || expression => body,
  //               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Guard clause.
}

// If-case statement:
if (something case somePattern when some || boolean || expression) {
  //                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Guard clause.
  body;
}

错误处理

//抛出给上层
throw FormatException('Expected at least 1 section');

//用on精细化操作,匹配不同异常
try {
  breedMoreLlamas();
} on OutOfLlamasException {
  // A specific exception
  buyMoreLlamas();
} on Exception catch (e) {
  // Anything else that is an exception
  print('Unknown exception: $e');
} catch (e) {
  // No specified type, handles all
  print('Something really unknown: $e');
}


try {
  breedMoreLlamas();
} catch (e) {
  print('Error: $e'); // Handle the exception first.
} finally {
  cleanLlamaStalls(); // Then clean up.
}

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CZDXWX

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值