flutter dart ts 语法对比

379 阅读3分钟

这一切的开始,都是由于电饭锅预约功能的缺失,而激发了自己写一个世界上最简单的 app 的想法——大米粥计时器。

用过电饭锅的人都知道,自带一个定时预约功能,比如,今天晚上9点26分把大米水都按一定比例准备好放到电饭锅里,计划明天早上7点13分做熟能吃。那么,按照现在电饭锅的预约功能,需要自己算剩余时间为:9小时47分,然后输入给电饭锅。

但是问题来了,每天这么算,头疼,只要算错了,提前了还好,晚的话,就吃不上大米粥。之前小米出过一款电饭锅,直接输入07:13即可自动算时间,但是几年后的今天,小米把这个功能去掉了。没办法,只能自己想办法。纠结了好久 uniapp,react native,flutter,最终选择了我认为最有未来的 flutter,因为他有自己的渲染引擎,一处开发所有端的样式都能保持一致,同时又保证了性能的丝滑。

语法对比

dart 语法与 ts 语法简单是太像了,像到我感觉是不是谷歌曾经想通过dart 来取代 js 了?

定义变量+赋值+定义函数
  • ts
let num: number = 10;
function add(x: number, y: number): number {
  return x + y;
}
  • dart
void main(){
  int num = 10;
  num = 100;
  num = "100";❌//报错,因为类型错误
  num = 100.0;❌//报错,因为双精度不能赋值给整型

  double c = 1.0;
  c = 10;✅//整型可以赋值给双精度

  var d = 1;
  d = 2;
  d = "2";❌//报错,因为类型错误
  
  const f = 1;
  f = 2;//报错,不能再赋值
  
  var a = 1;
  
  const x = 1; // 声明一个编译时常量 x,并赋值为 1,const 可以提高程序性能
  const y = x + 2; // 因为 x 是常量,所以加2后依然是常量没问题
  
  const z = y + a;❌//报错,因为a不是一个固定的值,所以不能用 const 定义
  final w = y + a;✅//通过 final 来定义


  final m = 1; // 虽然这样没问题,但是推荐使用 const 定义
  final n = m + 2; // 虽然这样没问题,但是推荐使用 const 定义
}

int add(int x, int y) {
  return x + y;
}
箭头函数 + 模板字符串
  • ts
const sum = (x: number): number => x * 2;
const sum = (x: number): number => {
    const y = 10;
    return x + y;
};

function greet(name: string): string {
  return `Hello, ${name}`;//ts 里叫模板字符串
}
  • dart
int sum(int x) => x * 2;//箭头函数只接受单独一条语句,不支持花括号,与 ts 不同。

//下面是错误示范
int sum(int x) => {❌//多条语句不支持,需要使用普通方式定义函数
  int y = 10;
  return x + y;
}
int sum(int x) {✅//其实比 ts更方便,因为 ts 普通函数需要 function定义
  int y = 10;
  return x + y;
}

String greet(String name) {//dart 里,这个叫 「字符串插值」
  return 'Hello, $name';
}
String greet(String a1) {//dart里模板字符串,通过三个单引号或三个双引号来实现
  return '''Hello, $a1
          Morning
          ok
  ''';
可选参数
  • ts
function printSomething(x: number, y?: number) {
  if (y) {
    console.log(`${x} ${y}`);
  } else {
    console.log(x);
  }
}

printName(1); // 输出 1
printName(1, 2); // 输出 1 2
  • dart 里可选参数分为
    • 命名可选参数,使用{ }包裹参数
    • 位置可选参数,使用[ ]包裹参数
//下面是可选命名参数 有默认值
int printSomething(int x, {int y = 0}) {
  if (y > 0) {
    print('$x $y');
  } else {
    print(x);
  }
  return 1;
}

//下面是可选位置参数 有默认值
int printSomethingTwo(int x, [int y = 0]) {
  if (y > 0) {
    print('$x $y');
  } else {
    print(x);
  }
  return 1;
}

//下面是可选命名参数 无默认值
int printSomethingThree(int x, {int? y}) {
  if (y != null && y > 0) {
    print('$x $y');
  } else {
    print(x);
  }
  return 1;
}

//下面是可选位置参数 无默认值
int printSomethingFour(int x, [int? y]) {
  if (y != null && y > 0) {
    print('$x $y');
  } else {
    print(x);
  }
  return 1;
}

void main() {
  printSomething(1); // 输出 1
  printSomething(1, y: 2); // 输出 1 2

  printSomethingTwo(1); //输出 1
  printSomethingTwo(1, 2); //输出 1 2

  printSomethingThree(1); //输出 1
  printSomethingThree(1, y: 2); //输出 1 2

  printSomethingFour(1); //输出 1
  printSomethingFour(1, 2); //输出 1 2
}
  • 结论:
    • 只要可选参数,必须有默认值,如果不想给默认值,类型后面要加问号,同时逻辑上要进行非null 判断
    • 只要是用 {} 包裹的参数,在函数调用时,必须用 参数名:参数值 的方式进行传值
泛型
  • ts
function identity<T>(arg: T): T {
  return arg;
}

const arr: number[] = [1, 2, 3];//这里的 number[]可能省略,能推荐出来
const result = identity<number[]>(arr); // result 的类型是 number[]

  • dart
T identity<T>(T arg) {
  return arg;
}

List<int> arr = [1, 2, 3];
var result = identity<List<int>>(arr); // result 的类型是 List<int>
面向对象,继承
  • ts
class Animal {
  private name: string;

  constructor(name: string) {
    this.name = name;
  }

  speak() {
    console.log(`${this.name} makes a noise.`);
  }
}
class Dog extends Animal {
  constructor(name: string) {
    super(name);
  }

  speak() {
    console.log(`${this.name} barks.`);
  }
}
const dog = new Dog();
dog.speak();
  • dart
class Animal {
  String name;

  Animal(this.name);

  void speak() {
    print('$name makes a noise.');
  }
}

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

  @override
  void speak() {
    super.speak(); //不是必须的
    print('$name barks.');
  }
}

void main() {
  Dog dog = Dog("John");//创建实例不需要 new 关键字
  dog.speak();
}
因为多态,实现接口等操作,平时写业务时,用的不多,这里就没再列出。对于有需要的时候,直接看文档就好了。这里只是放上最快的入门对比

如果时间允许,下一个文章写一下《大米粥计时器的代码讲解》