Dart 语法

image

Dart我们有不得不学的理由,因为有Flutter这尊大神在啊,但是像有的大神这样潇洒,现阶段我还做不到

如果您熟悉面向对象和基本编程概念(如变量、循环和条件控制),则可以完成本教程,您无需要了解Dart或拥有移动开发的经验

膜拜大神...... 初上Dart有种似曾相识的感觉,那是因为现在高阶语言基本趋同,Dart又是融合强类型语言和弱类型语言,所以还是不能直接跳过,要不然很多代码其实也是不怎么清楚的。再者对我自己来说,若是不把Dart系统的走一遍,还是会有朦胧感的,这样很不舒服的

本文重在给初次接触Dart的朋友提供帮助,内容涵盖基础语法,但是Dart的多线程、异步不在本文之列,那是下一篇的内容。同时呢自己上手操作下、再写一遍笔记,这样记得清楚,更是为以后着想,人过留名,雁过留声,我们学完了不写博客怎么证明我们学过了,以后忘了怎么办,那就是白学了嘛,希望大家都自己做笔记写博客、写文章

我写的很随自己的意思,大家看不惯的话请看下面写的很标准的:


Dart 特性

网上很多文章都说 Dart 在java 的基础上融会了高级语言的特性,但是我想说 java 最新版本就没有吗?所以这样说等于没说

要我说 Dart = java + kotlin,要是您接触过 python,那么 Dart = java + python 才是最恰当的,在 Dart 中您即可以编写传统 java 风格的代码,也可以编写类似 python 风格的代码,下面我尽量给大家展示出来 Dart 在那些方面像 python

1. 像 python 的地方

  • 1.1 Dart 支持库形式开发
    用过python的同学都知道是怎么回事,在java里我们创建一个class文件必须要在该文件内创建一个和该文件同名的类
public class Name {
    ......
}

但是Dart允许我们在Dart文件种不创建类,直接写属性、写方法,然后以库的方式给别人使用

image

DartLib 代码:

var name = "NAME";

void function1() {
  print(name);
}

void function2() {
  print("BBB");
}

以库的形式导入使用

import 'package:flutter_app4/DartLib.dart' as Lib;

void test(){
  Lib.name = "FUN";
  Lib.function1();
}
  • 1.2 Dart 允许大家像 python 那样声明变量
var book = Book("AA", 18);
  • 1.3 Dart 可以像 python 一样,方法声明时返回值可写可不写,编译器会自动判断返回类型的
  sum( var num1){
    return num1 + 10;
  }
  • 1.4 Dart 和 python 最大的区别:就是 Dart 不能像 python 那样可以处处省略参数类型,Dart 必须得写参数类型,{}、;也必须写,要不然 Dart 就真的和 python 差不多了

2. Dart 支持 var 动态类型

Dart 静动态类型都支持,再加上高级语言特性,这样就可以像怎么写就怎么写了,即可以写成传统的java面向对象、处处皆对象的代码风格,也可以像kotlin一样,还可以像python一样,现在语言的差异越来越小了,Dartpython的差异很小了,说实话,我是比较喜欢python的,极简是有种魔力的,粘上就忘不了了

3. Dart 有性能优势

Dart可以在没有锁的情况下进行对象分配和垃圾回收。就像JavaScript一样,Dart避免了抢占式调度和共享内存(因而也不需要锁),所以Dart可以更轻松地创建以60fps运行的流畅动画和转场。这个在你使用Dart开发出App之后必定会深有感触


基本数据类型

Dart 基本数据类型:

  • 动态类型 - vardynamic
  • 数值型 - Numintdoublebool(布尔值)
  • 集合型 - ListMap,Dart 没有数组的概念,数组就等于集合
  • 文本型 - String
  • 方法类 - Function

下面仔细说下:

1. vardynamic是动态类型

2. 新的数学类型 Num

intdouble大家知道是什么,那这个Num是仅限于数字的动态类型,数值可以是int也可以是double

  num name = 10;

  void test() {
    name = 11;
    name = 11.2;
  }

3. Dart 没有 kotlin 这么变态的非 null 要求,声明的变量初始值可以给 null

var name ;

4. var 的特性

var 声明的变量,初始值要是 null 的话,后面给什么值都可以,但只要 var 的变量给初始值明确类型了,那么后面就只能是这个类型的数据了

  // 这样 OK
  var name ;
  void test() {
    name = 11;
    name = "AA";
  }
  
  // 这样报错
  var name = 10;
  void test() {
    name = 11;
    name = "AA";
  }

5. dynamic

dynamic 是不确定类型和var是一样的,但是var是给开发人员用的,dynamic是Dart 内部用的,我们也可以写dynamic,但是一般有dynamic的地方都自动隐藏了,dynamic这个关键字自动提示是没有的,就是说Dart不建议我们使用dynamic,我们知道dynamic什么意思就行了:dynamic修饰的变量,可以赋给任何类型的值


运算符

常用的就不说了,说些有变化的

1. /

在java中取整,5/3=1;但是在Dart中就不是取整了,而是带小数点了,5/3=1.6666...

2. ~/ -

在Dart中是取整的意思,5/3=1

3. ==

Dart 的==判断的就不是引用一样不一样了,而是判断的等号2边内容一样不一样

4. identical(name1, name2)

identical在Dart中才是判断应用一样不一样的

5. ??=

给null赋值,若这个参数==null,那么就=后面的这个数,当然大家使用??也是可以的,??两边可以接表达式的

var name;
print(name ??= 10);
~~~~~~~~log~~~~~~~~~~~
I/flutter: 10

6. =>

单行时可以省略{}

Function test1 = (var name, var age) => print(name + age);

7. ..

进行链式调用,非常简便

    var book = Book("AA", 12)
      ..name = "BB"
      ..age = 15;

8. ?.

null的话不报错

  var book = Book("AA", 12, "CC");
  book?.name = "BB";

9. isis!as

类型判断,转换类型,详细不展开了,大家都知道

  if (book1 is Book) {
    book1.name = "AA";
  }

  (book2 as Book).name = "DD";

switch

Dart 中的 switch case 支持基本数据类型和对象类型,另外还可以给每个 case 加上别名,用于指定跳转到某个 case 执行代码

    var name = "BB";
    switch (name) {
      as:
      case "AA":
        print("AA");
        break;
      case "BB":
        print("BB");
        continue as;
        break;
      case "CC":
        print("CC");
        break;
    }
    
~~~~~~~~~log~~~~~~~~~
I/flutter: BB
I/flutter: AA

比如上面我们给AA这个case加上as这个标记之后,在BB中我们就可以使用continue这个关键字跳到AA这个case去执行代码,不管AA符不符合判断,后会执行AA这个case 的代码


方法上的变化

1. Dart 中方法都是有返回值的,即便我们写void其实也是返回的null,这点大家知道一下就行

2. 参数花样

Dart 用{}表示可选参数,用[]表示位置参数,没 python 好使

  // 可选参数,用 xx:xx 传值
  void test1(var name1, {var name2 = 10, var name3 = 20}) {
    print("result = $name1,$name2,$name3");
  }
  
  // 位置参数,位置是固定的,你要是想给 name3赋值,必须先给name2赋值
  void test2(var name1, [var name2, var name3]) {
    print("result = $name1,$name2,$name3");
  }
  
  test1("AA", name2: 55);
  test2("BB",18,19);

3. 方法皆对象

Dart 秉承高级语言的特性,一切解释对象,方法本身也不例外,熟悉 koltin、python 的朋友一定不会谋生

  void man(){
    print("man");
  }
  
  var f = man;
  f();

比如上面,我们可以声明一个属性对象,用别的方法赋值给该对象,然后加()的方式运行该方法

4. 参数方法

我们来看下 Dart 中方法作为参数的使用

  // 声明方法
  void textView(void click(var name)) => click("AA");
  // 使用方法
  textView((var name) => print(name));

5. 匿名方法

其实在上面4中就展示了匿名方法,这里再强调一下,Dart 中匿名方法语法:返回值 (参数类型 参数名,xxx){},没有返回值的可以不写,实现单行可以用=>代替{}

举个例子:

void textView(String click(var name)) => click("AA");
  
textView((var name) {
  print(name);
  return "AA";
});

6. 闭包

Dart 的闭包和 JS、python 一个意思,是定义在方法里面的方法,其特性:

  • 闭包是一个对象
  • 闭包定义在其他方法内部
  • 闭包可以访问外部方法的布局变量,并持有其状态。这是闭包的最大用途,通过闭包的方式把一个方法内部的属性暴露出去,因为方法是可以返回方法的,Dart 中方法也是对象一样可以当做返回值处理

很多人说闭包学不会,看了很多资料还是不明白,其实吧这样跟大家说:大家把闭包看成对象就行了

比如下面这个例子,我们拿到闭包,操作外层方法的数据不停的自增,我们对调用几次闭包,大家会发现Z合格数据是不停增加的

// 闭包
sum(){
  var num = 0;
  sum2(){
    num++;
    print(num);
  }
  return sum2;
  
  // 也可以这么写,匿名的方式用的最多
  return (){
    num++;
    print(num);
  };
}

// 多调用闭包几次
void main(){
  Function a = sum();
  a();
  a();
  a();
  a();
  a();
  a();
}

~~~~~~~~~~log~~~~~~~~~~
1
2
3
4
5
6

结果是不会骗人的,大家就把闭包看成是一个包含外层数据的匿名实现类,当成对象看就好理解了,这是最经典的一个例子


面向对象上的变化

1. 可以省略 new

上文说过 Dart 创建对象可以省略new,很棒的设计,体验上像 python 极简主义靠拢

var book = Book("AA", 12);

2. Dart 默认自带get/set方法

3. Dart 中方法是不能重载的

image

4. Dart 没有public,private

Dart 的可见范围是以library库为单位的,每一个 Dart 文件就是一个库,Dart 中_表示库级别私有,_即可以修饰变量,也可以修饰对象,还可以修饰方法,这点又是和 python 一样

// 这样的对象,除了这个库文件,哪也别想用,变量我就举例了
class _Book {
  var name, age;

  _Book(this.name, this.age);

  speak(){

  }
}

5. 计算属性

Dart 属性默认自动生成get、set方法,但是大家也可以自己写,但是自己写的get、set就有区别了,看下面:

class RectTest {
  var width, height;

  RectTest(this.width, this.height);

  get area => width * height;

  set area(value) => width = value;
}

void main() {
  var rect = RectTest(20, 12);
  print(rect.area);
  rect.area = 30;
  print(rect.area);
  print(rect.width);
}

~~~~~~~~~~~~~log~~~~~~~~~~~~~~~
240
360
30
  • 要自己写get、set的话,该属性就不能声明,写了get、set方法的话就当是生命了一个变量,该变量set方法中不能给自己赋值(会陷入无限递归的状态),只能给别的属性赋值,大家看例子中的结果也能看出来,可以自己试下

6. 构造方法

Dart 中构造方法变化较大

  • 6.1 首先 Dart 像 java 一样提供一个默认的空的构造方法,但是一旦我们自己实现构造方法的话,这个默认的构造方法就会失效,我们自己的写的构造方法会替代默认的构造方法,另外 Dart 也提供了便利的语法糖在里面
class Book {
  var name, age;
    
  // 标准写法
  Book(var name, var age){
    this.name = name;
    this.age = age;
   }
  
  // 语法糖1
  Book(this.name, this.age){
   }
  
   // 语法糖2
   Book(this.name, this.age);
}

有一点要明确,这样的构造方法里,this的赋值是在构造方法方法体之前执行的

  • 6.2 Dart 蛋疼的不支持重载,所以 Dart 提供了命名构造方法,就是类名+方法名的方式实现多构造方法
class Book {
  var name, age;

  Book(this.name, this.age);
  Book.withName(this.name);
  Book.withAge(this.age);
}

然后自动提示就可以显示有多个构造方法了


image
  • 6.3 常量构造方法,若是有一个对象他的值都不需要变化的话我们就可以使用常量构造函数构造一个常量,这样的话对象的值在编译期就能知道,运行速度上有优势,这个需要结合 const 使用,具体场景估计也就是枚举了吧
// const 的对象要求属性都是不可变的,也就是 final 的
class Book {
  final name, age;

  const Book(this.name, this.age);
}

void main() {
  const book = const Book(12,112);
}
  • 6.4 工厂构造方法,在普通构造方法前加factory关键字,这个是配和私有构造方法使用的,看下面的例子
class Book {
  var name, age;

  factory Book(var name){
    return Book._withName(name);
  }

  // 私有构造方法
  Book._withName(this.name);

  Book._withAge(this.age);

}
  • 6.5 给 final 赋值,final 描述的一般都是不可变的值,Dart 允许我们声明 final 时给个null,但是在代码运行前必须初始化,这个地方就是构造方法,方式有2种:

方式1:在构造方法后面跟:给 final 赋值

class Book {
  var name, age;

  final title;

  Book(this.name, this.age, var title) : this.title = title {}

}

方式2:直接在构造方法中赋值,利用this.xxx在方法体之前执行的特性

class Book {
  var name, age;

  final title;

  Book(this.name, this.age, this.title);
}
  • 6.6 对象call方法,高级语言中允许把方法当做对象使用,Dart 中允许大家把对象当方法使用book1(),本质是调用book1里面的指定方法call
class Book {
  var name, age;

  final title;

  Book(this.name, this.age, this.title);

  call( var value ){
    print("$name同学请$value同学上台演讲");
  }
}

void main() {
  var book1 = Book("AA", 12, "CC");
  var book2 = Book("AA", 12, "CC");

  book1("PP");
}

~~~~~~~~~~~~~~~log~~~~~~~~~~~~~~~~~~
AA同学请PP同学上台演讲

其实什么++,--之类的都是运用的这个思路,不过不推荐这个搞,这样会模糊对象和方法的边界,那代码就不好阅读理解了

7 继承

Dart 是单继承关系,子类不能继承父类的私有(属性、方法)和构造函数

Dart 最蛋疼的是就是继承关系中的构造函数了,Dart 的子类默认使用父类的默认构造函数,若是父类没有默认的构造函数了,而是用户自定义的,那么子类必须显示的继承父类的一个构造函数,看下面的例子:

class Animal {
  var name, sex;

  Animal(this.name);

  Animal.withSex(this.sex);
}

class Dog extends Animal {
  Dog(name) : super(name);

  Dog.withSex(sex) : super.withSex(sex);
}

情况再复杂一点的是加上 final 赋值,中间用相联

class Dog extends Animal {
  final price;

  Dog.withSex(var sex, var price)
      : this.price = price,
        super.withSex(sex);
}

8. 多继承

Dart 中多继承专门有个词:Mixins,Dart 允许我们使用with关键字实现多继承,但是多继承本身非常危险,很容易出现各种问题的

标准写法:

class Animal {
  var age, sex;
}

class Cat {
  var name;

  speak() {
    print("CAT");
  }
}

class Dog {
  var name;

  speak() {
    print("DOG");
  }
}

class Bear {
  var name;

  speak() {
    print("BEAR");
  }
}

class MyPet extends Animal with Dog, Cat, Bear {
  var n;

  MyPet(this.n);
}

然后我们调用下 pet.speak() 方法看看

  var pet = MyPet();
  pet.speak();
  
  ~~~~~~~~log~~~~~~~~
  BEAR

这说明对于多继承来说,多个父类同名的属性和方法是以最后一个继承的父类的数据为准

并且多继承对父类要求很严格,要求父类不能有自己的构造方法,默认的除外...蛋疼不,并且多继承很容易出问题的,使用时要格外注意

多继承进一步就是组合了,用于模块间和架构内的功能组合,看下面的代码,这块我也没有什么体验,也是道听途说

class MyPet1 = Animal with Dog;
class MyPet2 = Animal with Cat;
class MyPet3 = Animal with Bear;

我有3种不同功能的宠物,注意这样写的话要求 MyPet1 这样的子类不能有自己的属性和方法,纯粹是为了功能组合而存在,大家要清楚

9. 抽象类

Dart 的抽象类中的抽象方法不用写abstract关键字,一般认为 Dart 的抽象类更像是接口,一般都是当接口用的

abstract class Cat{
  void speak();
}

10. 接口

Dart 的接口实在是怪,Dart 中其实是没有接口这个概念的,在 Dart 里接口就是对象,我们用implements关键字可以直接继承一个对象,但是该对象中的所有属性和方法都需要我们重写

class Animal {
  var name, sex;

  Animal(this.name);

  Animal.withSex(this.sex);
}

class Dog implements Animal {
  @override
  var name;

  @override
  var sex;
}

所以这里就体现出上面说的抽象类的重要性了,Dart 里我们一般把接口写成抽象类

abstract class Cat{
  void speak();
}

class Dog implements Cat {
  @override
  void speak() {
    // TODO: implement speak
  }
}

11. Mixin 混入

Dart 的 implements 限制不小,比如你继承一个 dart 中的 接口,你必须重写这个接口里面所有的属性和方法,不管这个方法是不是抽象的

abstract class A {
  runA();

  speakA() {}
}

abstract class B {
  runB();
}

class AA implements A, B {
  @override
  runA() {
    // TODO: implement runA
    return null;
  }

  @override
  runB() {
    // TODO: implement runB
    return null;
  }

  @override
  speakA() {
    // TODO: implement speakA
    return null;
  }
}

这样明显限制太大,很多时候用着并不舒服,所以 Dart 提供一种新的接口类型:Mixin,你实现 Mixin 类型的接口后,这样你就可以像 java 那样去实现接口了,注意实现接口时要用:with

mixin A {
  runA();

  speakA() {}
}

mixin B {
  runB();
}

class AA with A, B {
  @override
  runA() {
    // TODO: implement runA
    return null;
  }

  @override
  runB() {
    // TODO: implement runB
    return null;
  }
}

12. 重写操作符

这是个骚操作,会让我们的代码看着非常高大上,什么是操作符:+,-,++,>这些就是,我们在class内部使用operator关键字+操作符号就可以给我们的对象添加诸如+,-,++,>这样的操作了

class Book{
  var price;
  var _name = "AA";

  Book(this.price);

  operator >( Book otherBook ){
    return this.price > otherBook.price;
  }

  operator [](String attribute){
    switch(attribute){
      case "price":{return price;}break;
      case "name":{return _name;}break;
      default: {return null;}
    }
  }
}

void main() {

  var book1 = Book(20);
  var book2 = Book(30);

  print( book1 > book2 );
  print( book1["price"] );
  print( book1["name"] );
}

book1["price"]这可以让我们换个方式调用对象的属性,装逼用的,大家看上面的写法就成,用这个方法可以在外面拿到对象的私有属性


泛型

Dart 中的泛型和 JAVA 语法差不多

1. 类中使用泛型

class Location {
  Object x;
  Object y;

  Location(this.x, this.y);
}

2. 方法中使用泛型

class Location<T> {
  T x;
  T y;

  Location(this.x, this.y);
}

3. 集合中使用泛型

  • 3.1 list
// 不使用泛型限制数据类型
var names = ['aa', 'bb', 'cc', 111];

// 使用泛型之后
var names = <String>['aa', 'bb', 'cc'];
  • 3.2 map
// 不使用泛型限制数据类型
var infos = {1: 'one', 'name': 'why', 'age': 18}; 

// 使用泛型之后
Map<String, String> infos = {'name': 'why', 'age': '18'};

库的导入

前面简单的说了下导库,这里咱们详细来说说

1. Dart 导库的3种方式:

  • Dart 标准库 - 这里库都是 Dart 内部自带的,比如:dart:io、dart:html、dart:math
import 'dart:io';
  • Pub 包管理器 - 使用前缀:package:,像 Flutter 提供的包就是用 Pub 管理器导入
import 'package:flutter/material.dart';
  • 指定路径 - 可以是相对路径或绝对路径
import 'lib/student/student.dart';

2. show、hide、as 关键字

  • show - 只导入指定的文件
  • hide - 隐藏指定文件,其他都导入
  • as - 起别名
import 'lib/student/student.dart' show Student, Person;
import 'lib/student/student.dart' hide Person;
import 'lib/student/student.dart' as Stu;

// 使用的使用要加上别名
Stu.Student s = new Stu.Student();

这点其实和 python 是一模一样的

3. library、part 定义库

我们可以用 library 给库起个名字,没名字的库你也没法用不是,然后当库很大时,一个文件装不下时 part 就起作用了, 使用 part 可以把子文件关联进库主文件中,库打包的时候一起都打进去,不会造成文件缺失

使用思路:

  • 子文件使用 part of "库名" 的方式关联库主文件
  • 库主文件使用 子文件名.dart 的方式把子文件绑定进库里

主文件 AB.dart

library AB
part "mathUtils.dart";
part "dateUtils.dart";

子文件 mathUtils.dart

part of "AB.dart";

int sum(int num1, int num2) {
  return num1 + num2;
}

恩,有些麻烦,需要子文件和主文件都相互声明,有点绕,初上手会很困惑的,好在一切不合理的都会被消灭,这东西现在过时啦

4. export 定义库

export 就是用来代替 path 的,在 export 的时代,我们只需要在库主文件声明一下需要的子文件就行啦,不用再折腾子文件了

主文件 AB.dart

library AB;

export "mathUtils.dart";
export "dateUtils.dart";

子文件 mathUtils.dart

int sum(int num1, int num2) {
  return num1 + num2;
}

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,482评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,377评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,762评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,273评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,289评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,046评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,351评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,988评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,476评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,948评论 2 324
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,064评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,712评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,261评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,264评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,486评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,511评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,802评论 2 345

推荐阅读更多精彩内容

  • 1、前言: 最近在学习Flutter,作为Flutter的编程语言,Dart语言语法的学习自然就编程重中之重。本文...
    Yagami3zZ阅读 1,486评论 0 0
  • 推荐个小工具:Flutter自动生成widget代码 ,只支持pc浏览器(不包括edge,ie) 注意: 跟Jav...
    西西西瓜sama阅读 1,643评论 0 1
  • 前言 Flutter应用程序使用Dart语言开发,Dart是面向对象编程语言,由Google于2011年推出,目前...
    子疯zp阅读 645评论 0 2
  • 本文是对 Dart 语言的官方文档做了简单的翻译和总结,有不当之处敬请指正。如果有时间和精力建议通读官方文档 he...
    小小小超子阅读 10,465评论 8 22
  • 1. 重要概念 能够放在变量中的所有内容都是对象,每个对象都是一个类的实例。甚至于数字、函数和null值都是对象,...
    凯玲之恋阅读 3,665评论 0 5