【叁③】dart语言基础

提莫队长正在待命

flutter是dart语言开发的一个移动开发ui框架,dart语言与其他各种高级语言非常类似。下面记录一些与c++或java不一样的语法。

Dart语言特点

  • dart语言可以开发 Web、移动端、PC、服务器端、物联网等平台应用
  • 面向对象,一切皆对象,强类型

num:数值变量类型
字符串常量:用'-'或"_"
字符串插值:用$varName或${varName}引用字符串
var:动态(dynamic)类型变量,一旦定义类型就确定下来(个人建议少用),如

var a;               //dynamic类型变量
a=10;               //第一次赋值为int,则后续都为int
a="adfadf";         //error

方法定义 (TODO:修订)

  • 顶级方法:定义在类外,类似于c++中的全局方法,
  • 静态方法:类中的静态方法,和c++一样
  • 实例方法:类的成员方法,和c++一样
  • 嵌套方法:定义在方法中的方法

变量定义:与方法类似,有顶级变量,静态变量,实例变量(属性)

dart只有公有和私有两种权限控制分类,以"_"开头的标识符在库内私有。
Dart 工具可以指出两种问题:警告和错误。 警告只是说你的代码可能有问题, 但是并不会阻止你的代码执行。 错误可以是编译时错误也可以是运行时错误。遇到编译时错误时,代码将 无法执行;运行时错误将会在运行代码的时候导致一个 异常。

未被初始化的变量,其值都为null。

final与const:都表示静态变量,const需要在编译时就需要赋值,final将赋值推迟到运行时,第一次赋值之后就不能改变了。
const还可以用来创建静态构造函数,这样的构造函数创造的值不能改变。

Keywords(关键字)

下表为 Dart 语言的关键字。

abstract 1 continue false new this
as 1 default final null throw
assert deferred 1 finally operator 1 true
async 2 do for part 1 try
async 2* dynamic 1 get 1 rethrow typedef 1
await 2 else if return var
break enum implements 1 set 1 void
case export 1 import 1 static 1 while
catch external 1 in super with
class extends is switch yield 2
const factory 1 library 1 sync 2* yield 2*

带有上标 1 的关键字是内置关键字,避免把内置关键字当做标识符使用,也不要把内置关键字用作类名字和类型名字。 有些内置关键字是为了方便把 JavaScript 代码移植到 Dart 而存在的。 例如,如果 JavaScript 代码中有个变量的名字为 factory, 在移植到 Dart 中的时候,你不必重新命名这个变量。

带有上标 2 的关键字,是在 Dart 1.0 发布以后又新加的,用于支持异步相关的特性,不能在标记为 asyncasync*、或者 sync* 的方法体内 使用 asyncawait、或者 yield 作为标识符。 详情请参考:异步支持。

所以其他单词都是 保留词。 你不能用保留词作为关键字。

内置类型

1、数值类型

num,int( -253 和 253 ),double(双精度浮点),int和double是num的子类。

2、字符串

Dart 字符串是 UTF-16 编码的字符序列。 可以使用单引号或者双引号来创建字符串,用$varName${varName}引用字符串,支持+,==操作,用三个单引号包含创建多行字符。

3、布尔类型

bool,与c++不同的是,bool变量只有为true时,才为真,其他都为假,就算1也为假。

4、列表

List a=[1,2,3];

5、表

map,与c++ stl中map类似,不同的是构造增加了这种构造方法

var nobleGases = {
// Keys  Values
  2 :   'helium',
  10:   'neon',
  18:   'argon',
};

6、符号(Runes)

用于在字符串中表示 Unicode 字符,在 Dart 中,runes 代表字符串的 UTF-32 code points。
Unicode 为每一个字符、标点符号、表情符号等都定义了 一个唯一的数值。 由于 Dart 字符串是 UTF-16 code units 字符序列, 所以在字符串中表达 32-bit Unicode 值就需要 新的语法了。

通常使用 \uXXXX 的方式来表示 Unicode code point, 这里的 XXXX 是4个 16 进制的数。 例如,心形符号 (♥) 是 \u2665。 对于非 4 个数值的情况, 把编码值放到大括号中即可。 例如,笑脸 emoji () 是 \u{1f600}

String 类 有一些属性可以提取 rune 信息。 codeUnitAtcodeUnit 属性返回 16-bit code units。 使用 runes 属性来获取字符串的 runes 信息。

7、Symbols

一个 Symbol object 代表 Dart 程序中声明的操作符或者标识符。使用 Symbol 字面量来获取标识符的 symbol 对象,也就是在标识符 前面添加一个 # 符号。不懂,不用

Function类型

方法也是一种类型,方法可以赋值给变量,也可以作为参数传递给另一个方法,实现回调。
对于只有一个表达式的方法,你可以选择 使用缩写语法来定义:(鸡肋

bool isNoble(int atomicNumber) => _nobleGases[atomicNumber] != null;

参数

普通参数

//声明
 int foo(int a,int b){}
//调用
foo(1,2);

可选命名参数

//声明
int foo({int a,int b}){}
//调用
foo(a:1);
foo(a:1,b:2);

可选位置参数

//声明
int foo(int a,[int b])
//调用
foo(1);
foo(1,2);

参数默认值

//声明
int foo(int a=1,int b=2){}
//调用
foo();

匿名方法

即lambda表达式

作用域

大括号内定义的变量只能大括号没访问,大括号内可以方位大括号前面定义的变量。

返回值、

没指定返回值会自动插入return null作为最后个语句。

操作符

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
+ - - * / ~/ % == != > < >= <= as is is!
= += -= *= /= ~/= %= >>= <<= &= I= ^= ll && &
l ^ ~ << >> ?: ?? .. () [] . ?.

比较特别的有

操作符 用法 说明
/ a/b 除法操作,返回double
~/ a~/b 求商操作,返回整数
% a%b 取余操作,返回整数
is if(a is b) 判断a类似是否是b类型的,只有当 obj 实现了 T 的接口, obj is T 才是 true。例如 obj is Object 总是 true。
is! if(a is! b) 相当于if ( ! ( a is b ) )
as (a as b).name() 将a的类型转换为b,无法转换(类似于不是继承关系)则抛出异常
?? int a=b??c; 类似于?:,如果b为non-null,返回b,否则返回c
.. list..add(1)..add(2) 级联操作。第一个表达式返回一个 selector 对象。 后面的级联操作符都是调用这个对象的成员, 并忽略每个操作的返回值。级联操作可以嵌套
?. foo?.bar 如果foo为null则发挥null,则返回成员bar

流程控制

控制方法 说明
if else 条件分支
for for循环
while while循环
do while do while 循环
switch case 开关,与c++不同的是case可以是int,string或者编译时常量,另外,如果某个非空case的处理结束没有break,就会报错(c++中不会报错,而是继续执行下个case直到遇到break)。
break 跳出循环或者switch
continue 继续下一次循环
assert 断言,只在调试模式下有效,发布模式无效,调试模式如果条件不满足,就会抛出异常

遍历

foreach

实现了iterable接口的类可以使用foreach进行遍历,如:

List list=[1,2,3];
list.foreach((item)=>print(item));

for-in

某些实现了iterable的类还支持for-in遍历,类似于c++中的(for :)遍历

var list=[1,2,3];
for(var x in list){
print(x);
}

Exception(异常)

throw

抛出异常,可以抛出预定义异常,也可以抛出任何任何对象作为异常

throw new FormatException();
throw "this is a exception";

try-catch/on

try内可以尝试执行某个语句块,然后用catch或on或同时使用捕获该语句块中的异常并处理,on指定异常类型,catch的参数指定捕获到的异常,如果没有on,则可以捕获任意类型的异常。on-catch可以有多个。

rethrow

rethrow可以将异常重新抛出,给上层处理。

finally

finally在异常处理语句之后,无论是否捕获到异常,finally中的语句都会被执行。如果有异常但是没有对应catch来处理,则处理完finally之后,异常继续抛出。

一个综合的栗子(TODO:修订)

class MyException{
   String what="this is a exception";
};

void foo(){
  print("run foo");
  throw MyException;
}
void bar(){
  try{
    print("run bar");
    foo();
  }catch(e){
    print(e.what);
    rethrow;
  }finally{
    print("bar over");
  }
}

void main(){
  try {
    foo();
  }catch(e){
    print(e.what);
}

class(类)

与c++中不同的地方如下

单继承

dart中的类是单继承的,都最终继承自object类

this和super

this指向当前对象,super指向父类对象。

构造函数语法糖

如果构造函数只需要给成员赋值,可以简化为:

class ClassName{
    ClassName(this.a,this.b);
    int a;
    int b;
}

等价于

class ClassName{
    ClassName(int x,int y){
        a=x;
        b=y;
    }
    int a;
    int b;
}

Redirecting constructors(重定向构造函数)

有时候一个构造函数会调动类中的其他构造函数。 一个重定向构造函数是没有代码的,在构造函数声明后,使用 冒号调用其他构造函数。

class Point {
  num x;
  num y;

  // The main constructor for this class.
  Point(this.x, this.y);

  // Delegates to the main constructor.
  Point.alongXAxis(num x) : this(x, 0);
}

Constant constructors(常量构造函数)

如果你的类提供一个状态不变的对象(即一旦定义就不能修改成员,只能访问)你可以把这些对象 定义为编译时常量。要实现这个功能,需要定义一个 const 构造函数, 并且声明所有类的变量为 final。

class ImmutablePoint {
  final num x;
  final num y;
  const ImmutablePoint(this.x, this.y);
  static final ImmutablePoint origin =
      const ImmutablePoint(0, 0);
}

Factory constructors(工厂方法构造函数)

如果一个构造函数并不总是返回一个新的对象,则使用 factory 来定义 这个构造函数。例如,一个工厂构造函数 可能从缓存中获取一个实例并返回,或者 返回一个子类型的实例。

下面代码演示工厂构造函数 如何从缓存中返回对象。

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

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

  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);
    }
  }
}

注意: 工厂构造函数无法访问 this。

使用 new 关键字来调用工厂构造函数。

var logger = new Logger('UI');
logger.log('Button clicked');

method(函数)

你可能感兴趣的:(【叁③】dart语言基础)