程序员All in FlutterFlutter中文社区

Dart 语法学习笔记

2019-03-02  本文已影响5人  TimBao

变量

声明变量几种方式:

1. var name     = "Tim";   //自动推倒类型(infer)为string
2. String name  = "Tim";   //强类型定义
3. dynamic name = "Tim";   //可以修改变量类型 name = 4.0;
4. final name   = "Tim";   //首次使用时执行一次
5. const name   = "Tim";   //类似全局常量或者static,编译期间确定值

如果没有赋初始值,默认变量初始值为null。

内置类型

  1. Numbers: 编译期间的数字类型的常量

    • int: 不大于64位,具体取决于平台
    • double: 64位

    int 类实现了位移运算符;
    支持0x十六进制;
    浮点型支持科学计数法

  2. Strings: UTF-16 unicode 编码

    语法跟python类似

    • &{express} 可以嵌入变量或者表达式
    • ''' ''' 或者 """ """,可以多行显示
    • r'', raw字符串
    • In Dart, runes are the UTF-32 code points of a string.
  3. Booleans: 同样是编译期间常量。

    • bool 标识符,true & false
    • if (nonbooleanValue) 这样比较是不行的,必须显示的比较或者调用类isEmpty方法。
  4. Lists: 数组

    • 如果想要声明一个编译期常量的数组:var constantList = const [1, 2, 3]; //必须指定为const
  5. Maps: 字典 同js

  6. Runes: UTF-32 字符串。比如一些符号,表情等。\uXXXX

  7. Symbols: 不会用到。针对API推断标识符有用。

函数

Dart是一个真正的面向对象编程语言,一切都是对象,函数也是一个对象,它的类型是Function。

跟c语言函数语法一样,但是可以省略返回值类型和参数类型。

也有自己的速写语法:

bool isNoble(int atomicNumber) => _nobleGases[atomicNumber] != null;
等价于
bool isNoble(int atomicNumber) {
  return _nobleGases[atomicNumber] != null;
}

=> expr{ return expr; } 的简写。expr只能是一个语句,否则必须用{}方式。

一、参数

1. 函数调用时,可以使用 name:value方式制定参数。顺序可以不是声明顺序。
2. @require 关键字,标示该参数必须传入。
3. 可选参数,使用[]扩起来。必须放到参数的最后位置,且不能存在多个[]的可选位置参数。
4. 参数可以设置默认值,如果没有设置默认值,默认为null。

二、.. 操作符,可以看作是链式编程的语法。object.func1()..func2()..func3();
三、函数可以作为参数传递给函数,作用同对象参数一样。
四、匿名函数、lambda表达式、闭包。是一个概念。
五、返回值:所有函数都有一个返回值,默认返回return null;

运算符

很多操作跟c运算符一致,这里不做过多介绍。下面只介绍特殊运算符:

~/: 除法,返回整数

as: 类型判断

is、is!: 类型检测

..: 严格来说,double dot不是操作符,而是Dart的语法。对同一个对象做一系列操作,类似链式编程。

??=: 赋值,只有当左值为null的时候,才赋值。
// 只有当b是null的时候,给b赋值value; 否则b保持原值不变
b ??=: value;

??: 条件运算符,简化if..else语句。expr1 ?? expr2,如果expr1不为null, 返回expr1; 否则返回expr2。

?.: 类似.操作符,获取成员。问号的作用是标示对象可以是null

控制流

var command = 'CLOSED';
switch (command) {
  case 'CLOSED':
    executeClosed();
    continue nowClosed;
  // Continues executing at the nowClosed label.

  nowClosed:
  case 'NOW_CLOSED':
    // Runs for both CLOSED and NOW_CLOSED.
    executeNowClosed();
    break;
}

异常处理

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 {
  // ···
} on Exception catch (e) {
  print('Exception details:\n $e');
} catch (e, s) {
  print('Exception details:\n $e');
  print('Stack trace:\n $s');
}
void misbehave() {
  try {
    dynamic foo = true;
    print(foo++); // Runtime error
  } catch (e) {
    print('misbehave() partially handled ${e.runtimeType}.');
    rethrow; // Allow callers to see the exception.
  }
}

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

// If p is non-null, set its y value to 4.
p?.y = 4;
var p1 = Point(2, 2);
var p2 = Point.fromJson({'x': 1, 'y': 2});
class Point {
  num x, y;

  Point(num x, num y) {
    // Use this only when there is a name conflict
    this.x = x;
    this.y = y;
  }
  
  // Syntactic sugar for setting x and y
  // before the constructor body runs.
  // Point(this.x, this.y); 等同于上面的构造函数,写法更简单
  
  // Named constructor:使用:Point p = Point.origin();
  Point.origin() {
    x = 0;
    y = 0;
  }
}

如果不写构造函数,会默认生成一个构造函数;默认生成的构造函数跟类同名,没有参数。

构造函数不能继承。默认子类会调用基类的默认构造函数或者无参数构造函数。

跟C++一样,Dart也有初始化列表(initializer list)。初始化列表要写在调用基类构造函数之前。

// Initializer list sets instance variables before
// the constructor body runs.
Point.fromJson(Map<String, num> json)
    : x = json['x'],
      y = json['y'] {
  print('In Point.fromJson(): ($x, $y)');
}

重定向构造函数:重定向构造函数的函数体必须为空,通过冒号在后面定向到其他构造函数.

class Point {
  num x, y;

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

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

常量构造函数:可以创建一个编译时的常量对象,对象构造函数参数必须时常量。用于创建一个不变的对象(内部成员不会改变)

class ImmutablePoint {
  static final ImmutablePoint origin =
      const ImmutablePoint(0, 0);

  final num x, y;

  const ImmutablePoint(this.x, this.y);
}

工厂构造函数:不能直接使用this。可以从cache获取实例,也可能创建子类型的对象。

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 = Logger._internal(name);
      _cache[name] = logger;
      return logger;
    }
  }

  Logger._internal(this.name);

  void log(String msg) {
    if (!mute) print(msg);
  }
}
 class Rectangle {
 num left, top, width, height;

 Rectangle(this.left, this.top, this.width, this.height);

 // Define two calculated properties: right and bottom.
 num get right => left + width;
 set right(num value) => left = value - width;
 num get bottom => top + height;
 set bottom(num value) => top = value - height;
 }

抽象方法:类似C++中的虚基类中的虚函数,基类中没有实现,子类实现。

// A person. The implicit interface contains greet().
class Person {
  // In the interface, but visible only in this library.
  final _name;

  // Not in the interface, since this is a constructor.
  Person(this._name);

  // In the interface.
  String greet(String who) => 'Hello, $who. I am $_name.';
 }

// An implementation of the Person interface.
class Impostor implements Person {
  get _name => '';

  String greet(String who) => 'Hi $who. Do you know who I am?';
}

String greetBob(Person person) => person.greet('Bob');

void main() {
  print(greetBob(Person('Kathy')));
  print(greetBob(Impostor()));
}

class Point implements Comparable, Location {...}

泛型

可以在运行时判断泛型类型内容的具体type。其他方面跟java或者c++差不多。

库和可见性

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

// Uses Element from lib1.
Element element1 = Element();

// Uses Element from lib2.
lib2.Element element2 = lib2.Element();
// Import only foo.
import 'package:lib1/lib1.dart' show foo;

// Import all names EXCEPT foo.
import 'package:lib2/lib2.dart' hide foo;
import 'package:greetings/hello.dart' deferred as hello;

Future greet() async {
  await hello.loadLibrary();
  hello.printGreeting();
}

异步支持

关键字asyncawait支持异步编程。

生成器

参考python中的生成器。
需要后续加强了解

可调用的类

Dart 语言中为了能够让类像函数一样能够被调用,可以实现call()方法。
具体使用的场景,需要调研

隔离

沙盒?

Typedefs

Dart中,函数也是对象。Function关键字,typedefs 可以给函数设置别名。

元数据

A metadata annotation begins with the character @, followed by either a reference to a compile-time constant (such as deprecated) or a call to a constant constructor.

Two annotations are available to all Dart code: @deprecated and @override.

注释

上一篇 下一篇

猜你喜欢

热点阅读