Dart语法基础

变量

变量的声明以及赋值:

//如果不初始化,则后续可以赋值任意类型,最终类型是dynamic类型,dynamic类型不会检测成员
var name = "Bozo";
复制代码

在声明变量的时候,也可以选择使用具体的数据类型:

//使用确定类型定义变量,赋值必须是相同类型
String name = "bozo";
int age = 12;
double height = 176.3;
bool onLine = true;
复制代码

没有初始化变量默认值都为null,即使变量类型为bool或者int

Dart中的基本数据类型:numdoubleintStringListSetStringmapboolrunesSymbolObjectdynamic

Dart中所有数据类型都是对象,都继承自Object类,null也继承自Object

const&final

使用constfinal定义的变量都只能赋值一次,并且在声明的时候必须进行初始化。

使用const定义的集合都是只读的,特性会传递到子元素,在内存中会复用相同内容对象,而final则不会作用于子元素,在内存中也不会复用相同对象

//不可以通过 list[0] = 5; 来修改集合中元素的值, 如果换做final来定义则可以修改
const list = [1,2,3,4];
const list2 = [1,2,3,4];
//此时输出的结果为 true, 如果集合是用final定义的则输出结果为 false
print(identical(list, list2));
复制代码

实例变量可以为final但是不能是const

方法

方法可以赋值给变量,也可以当作其他方法的参数,以下为定义方法的示例:

bool isEmpty(String str){
  return str == null || str == "";
}

//可以忽略类型定义
isEmpty(str){
  return str == null || str == "";
}

//如果是只有一个表达式的方法,则可以使用缩写语法来定义
isEmpty(str) => str == null || str == "";
复制代码

在Dart中方法还可以设置可选参数,以及设置默认值

void main() {
  printInfo("Bozo", 13, true);
  //可选位置参数
//  printInfo("Bozo", false);
  //可选命名参数
//  printInfo(name: "Bozo", showAge: false);
  //指定默认值
//  printInfo(name: "Bozo", showAge: true);
}

printInfo(name, age, showAge) {
  if (showAge) {
    print("name:$name,age:$age");
  } else {
    print("name:$name");
  }
}

//可选位置参数
printInfo(name, showAge, [age]) {
  ......
}

//可选命名参数
printInfo({name, age, showAge}) {
  ......
}

//指定默认值
printInfo({name, age = 12, showAge}) {
  ......
}
复制代码

所有函数都有一个返回值,如果没有指定返回值,则默认把return null;作为函数得最后一个语句执行

操作符

操作符重载

以下操作符可以被重载

例如重写+-操作符

class Vector{
  final int x;
  final int y;

  Vector(this.x, this.y);

  Vector operator +(Vector v){
    return Vector(x + v.x, y + v.y);
  }

  Vector operator -(Vector v){
    return Vector(x - v.x, y - v.y);
  }
}

void main(){
  Vector v1 = Vector(4, 3);
  Vector v2 = Vector(2, 1);

  Vector v3 = v1 - v2;
  Vector v4 = v1 + v3;

  //print: v3:x=2,y:2
  print("v3:x=${v3.x.toString()},y:${v3.y.toString()}");
  //print: v4:x=6,y:5
  print("v4:x=${v4.x.toString()},y:${v4.y.toString()}");
}
复制代码

如果覆写的操作符是==,则还应覆写对象的hashCode getter 函数

类型判定操作符

asisis!操作符是在运行时判定对象类型的操作符

操作符解释
as类型转换
is如果对象是指定的类型返回true
is!如果对象是指定的类型返回false
级联操作符

级联操作符 (..) 可以在同一个对象上 连续调用多个函数以及访问成员变量,使用级联操作符可以避免创建 临时变量

void main() {
  Person()
    ..name = 'bozo'
    ..age = 12
    ..contact = (new Contact()
      ..phoneNumber = '126854315'
      ..email = 'bozo@gmail.com')
    ..showInfo();
}

class Person {
  String name;
  int age;
  Contact contact;

  showInfo() {
  print("Name:${this.name},Age:${this.age},PhoneNumber:${this.contact.phoneNumber},Email:${this.contact.email}");
  }
}

class Contact {
  String phoneNumber;
  String email;
}
复制代码

异常

抛出异常
throw new FormatException('Expected at least 1 section!');

//还可以抛出任意对象
throw 'Out of llamas!'
复制代码
捕获异常
try {
    throwExceptionsFuc();
  } on FormatException {
    ...
  } on Exception catch (e) {
    ...
  } catch (e) {
    ...
  } finally {
    ...
  }
}
复制代码

可以使用on或者catch来声明捕获语句,也可以同时使用。使用on来指定异常类型,使用catch来捕获异常对象,函数catch可以有一个或两个参数,第一个参数为抛出的异常对象,第二个为堆栈信息

还可以使用rethrow关键字来把捕获的异常重新抛出

try{
    testFuc();
} catch (e) {
    ...
    //重新抛出异常
    rethrow;
}
复制代码

Dart中每个对象都是一个类的实例,所有类都继承于Object

构造函数

在Dart中可以使用this关键字来简化构造函数的实现:

class Person{
    String name;
    int age;
    
    //原始写法
    Person(String name, int age){
        this.name = name;
        this.age = age;
    }
    //使用this关键字简化写法
    Person(this.name, this.age);
}
复制代码

如果没有定义构造函数,跟Java中一样会有一个默认的无参构造

使用命名构造函数可以为一个类实现多个构造函数,如果要在一个构造函数中调用其他构造函数则使用重定向构造函数

void main() {
  Person person1 = new Person("Bozo", 17);
  Map map = new Map();
  map['name'] = "bozo";
  map['age'] = 18;
  Person person2 = new Person.fromMap(map);
}

class Person {
  String name;
  int age;

  Person(this.name, this.age);

  //命名构造函数
  Person.fromMap(Map map) {
    this.name = map['name'];
    this.age = map['age'];
  }
  
  //重定向构造函数
  Person.byName(name) : this(name, 0);
}
复制代码

如果要类提供一个状态不变的对象,则可以把对象定义为编译时常量。需要定义一个const构造函数,并且声明所有的变量为final。使用常量构造函创建的对象具有复用性,前提是对象的成员变量值相同。

class Car {
  final String color;

  const Car(this.color);

  static final Car car = const Car("red");
}

void main(){
    Car car1 = const Car("red");
    Car car2 = const Car("black");
    
    //断言执行通过,car1跟car为同一个对象
    assert(identical(car1, Car.car));
    //断言执行失败
    assert(identical(car2, Car.car));
}
复制代码

如果一个构造函数不是总是返回一个新的对象,则可以使用factory关键字来创建工厂方法构造函数

class Logger {
  final String name;
  bool mute = false;

  // _cache is library-private, thanks to the _ in front
  // of its name.
  static final Map<String, Logger> _cache =
      <String, Logger>{};

  factory Logger(String name) {
    if (_cache.containsKey(name)) {
      return _cache[name];
    } else {
      final logger = new Logger._internal(name);
      _cache[name] = logger;
      return logger;
    }
  }

  Logger._internal(this.name);

  void log(String msg) {
    if (!mute) {
      print(msg);
    }
  }
}

void main(){
    var logger = new Logger('UI');
	logger.log('Button clicked');
}
复制代码

工厂方法无法访问this

extends 跟 implements
  • extends :继承其他类的属性以及方法,在dart中可以使用with关键字来实现多继承

    class A extends B with C,D{
        ...
    }
    复制代码
  • implements:一个类可以通过 implements 关键字来实现一个或者多个接口, 并实现每个接口定义的 API

枚举

使用 enum 关键字来定义枚举类型,枚举中每个值都有一个index的属性(从0开始)。枚举的values常量可以返回所有的枚举值

enum Color{
    RED,
    GREEN,
    BLUE
}

void main(){
    List<Color> colors = Color.values;
	assert(colors[2] == Color.BLUE);
}
复制代码

泛型

在Dart中使用泛型的方式与Java类似:

abstract class Cache<T>{
  T getByKey(String key);
  void cacheByKey(String key, T value);
}
复制代码

限制泛型的具体类型:

class SomeClass<T extends SomeBaseClases>{
    ...
}
复制代码

泛型函数:

T findByIndex<T>(List<T> data, int index) {
    return data == null ? data[index] : null;
}
复制代码

使用 import 来导入库

//内置库使用 dart:scheme
import 'dart:io';
//其他库使用文件系统路径或者 package:scheme
import 'package:libs/utils.dart';
复制代码

如果导入的两个库具有冲突的标识符,则可以使用库的前缀来区分,例如lib1跟lib2中都存在名为SomeClass的类:

import 'package:libs/lib1.dart';
import 'package:libs/lib2.dart' as lib2;

...
    
SomeClass class1 = new SomeClass();
lib2.SomeClass class2 = new lib2.SomeClass();
复制代码

如果只想导入库的一部分内容可以使用 showhide

// Import only foo.
import 'package:lib1/lib1.dart' show foo;

// Import all names EXCEPT foo.
import 'package:lib2/lib2.dart' hide foo;
复制代码

如果要让一个库在使用的时候才加载则可以使用延时加载库。如:

//使用 deferred as 导入
import 'package:deferred/hello.dart' deferred as hello;
//当需要使用的时候,使用库标识符调用loadLibrary()函数来加载库
hello.loadLibrary();
hello.sayHello();
复制代码
  • 一个库可以调用 loadLibrary() 函数,但该库只会载入一次
  • 延迟加载库的常量在导入的时候是不可用的。 只有当库加载完毕的时候,库中常量才可以使用。
  • 在导入文件的时候无法使用延迟库中的类型。 如果你需要使用类型,则考虑把接口类型移动到另外一个库中, 让两个库都分别导入这个接口库。
  • Dart 隐含的把 loadLibrary() 函数导入到使用 deferred as *的命名空间* 中。 loadLibrary() 方法返回一个 Future。

异步

异步方法的声明是添加 async 关键字,如:

...
checkVersion() async{
    ...
}
复制代码

使用await来等待异步方法返回:

...
//要使用 await,其方法必须带有 async 关键字
checkVersion() async{
    var version = await getVersionInfo();
    ...
}
复制代码

转载于:https://juejin.im/post/5c8265cde51d45711340d01f

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值