Flutter学习(二)Dart语法

简介

Dart 在静态语法方面和 Java 非常相似,如类型定义、函数声明、泛型等,而在动态特性方面又和 JavaScript 很像,如函数式特性、异步支持等。除了融合 Java 和 JavaScript 语言之所长之外,Dart 也具有一些其他很有表现力的语法,如可选命名参数、..(级联运算符)和?.(条件成员访问运算符)以及??(判空赋值运算符)。

一、变量声明

1.var 关键字

类似于 JavaScript 中的var,它可以接收任何类型的变量,但最大的不同是 Dart 中 var变量一旦赋值,类型便会确定,则不能再改变其类型,如:

var t = "hi world";
// 下面代码在dart中会报错,因为变量t的类型已经确定为String,
// 类型一旦确定后则不能再更改其类型。
t = 1000;

上面的代码在 JavaScript 是没有问题的,前端开发者需要注意一下,之所以有此差异是因为 Dart 本身是一个强类型语言,任何变量都是有确定类型的,在 Dart 中,当用var声明一个变量后,Dart 在编译时会根据第一次赋值数据的类型来推断其类型,编译结束后其类型就已经被确定,而 JavaScript 是纯粹的弱类型脚本语言,var只是变量的声明方式而已。

2.dynamic 和 Object

Object 是 Dart 所有对象的根基类,也就是说在 Dart 中所有类型都是Object的子类(包括FunctionNull),所以任何类型的数据都可以赋值给Object声明的对象。 dynamicObject声明的变量都可以赋值任意对象,且后期可以改变赋值的类型,这和var是不同的,如:

dynamic t;
Object x;
t = "hi world";
x = 'Hello Object';
//下面代码没有问题
t = 1000;
x = 1000;

dynamicObject不同的是dynamic声明的对象编译器会提供所有可能的组合,而Object声明的对象只能使用Object的属性与方法, 否则编译器会报错,如:

dynamic a;
Object b = "";
main() {
   a = "";
   printLengths();
}   
printLengths() {
  // 正常
  print(a.length);
  // 报错 The getter 'length' is not defined for the class 'Object'
  print(b.length);
}

dynamic的这个特点使得我们在使用它时需要格外注意,这很容易引入一个运行时错误,比如下面代码在编译时不会报错,而在运行时会报错:

print(a.xx); // a是字符串,没有"xx"属性,编译时不会报错,运行时会报错
3.final和const

如果从未打算更改一个变量,那么使用finalconst,不是var,也不是一个类型。 一个final变量只能被设置一次,两者区别在于:const 变量是一个编译时常量(编译时直接替换为常量值),final变量在第一次使用时被初始化。被final或者const修饰的变量,变量类型可以省略,如:

//可以省略String这个类型声明
final str = "hi world";
//final String str = "hi world"; 
const str1 = "hi world";
//const String str1 = "hi world";
4.空安全(null-safety)

Dart 中一切都是对象,这意味着如果我们定义一个数字,在初始化它之前如果我们使用了它,假如没有某种检查机制,则不会报错,比如:

test() {
  int i; 
  print(i*8);
}

在 Dart 引入空安全之前,上面代码在执行前不会报错,但会触发一个运行时错误,原因是 i 的值为 null 。但现在有了空安全,则定义变量时我们可以指定变量是可空还是不可空。

int i = 8; //默认为不可空,必须在定义时初始化。
int? j; // 定义为可空类型,对于可空变量,我们在使用前必须判空。

// 如果我们预期变量不能为空,但在定义时不能确定其初始值,则可以加上late关键字,
// 表示会稍后初始化,但是在正式使用它之前必须得保证初始化过了,否则会报错
late int k;
k=9;

如果一个变量我们定义为可空类型,在某些情况下即使我们给它赋值过了,但是预处理器仍然有可能识别不出,这时我们就要显式(通过在变量后面加一个”!“符号)告诉预处理器它已经不是null了,比如:

class Test{
  int? i;
  Function? fun;
  say(){
    if(i!=null) {
      print(i! * 8); //因为已经判过空,所以能走到这 i 必不为null,如果没有显式申明,则 IDE 会报错
    }
    if(fun!=null){
      fun!(); // 同上
    }
  }
}

上面中如果函数变量可空时,调用的时候可以用语法糖:

fun?.call() // fun 不为空时则会被调用

二、函数

Dart是一种面向对象的语言,所以即使是函数也是对象,并且有一个类型Function。这意味着函数可以赋值给变量或作为参数传递给其他函数,这是函数式编程的典型特征。

1.函数声明
bool isNoble(int atomicNumber) {
  return _nobleGases[atomicNumber] != null;
}

Dart函数声明如果没有显式声明返回值类型时会默认当做dynamic处理,注意,函数返回值没有类型推断

typedef bool CALLBACK();

//不指定返回类型,此时默认为dynamic,不是bool
isNoble(int atomicNumber) {
  return _nobleGases[atomicNumber] != null;
}

void test(CALLBACK cb){
   print(cb()); 
}
//报错,isNoble不是bool类型
test(isNoble);

对于只包含一个表达式的函数,可以使用简写语法:

bool isNoble (int atomicNumber)=> true ;   
2.函数作为变量
var say = (str){
  print(str);
};
say("hi world");
3.函数作为参数传递
//定义函数execute,它的参数类型为函数
void execute(var callback) {
    callback(); //执行传入的函数
}
//调用execute,将箭头函数作为参数传递
execute(() => print("xxx"))
(1)可选的位置参数

包装一组函数参数,用[]标记为可选的位置参数,并放在参数列表的最后面:

String say(String from, String msg, [String? device]) {
  var result = '$from says $msg';
  if (device != null) {
    result = '$result with a $device';
  }
  return result;
}

下面是一个不带可选参数调用这个函数的例子:

say('Bob', 'Howdy'); //结果是: Bob says Howdy

下面是用第三个参数调用这个函数的例子:

say('Bob', 'Howdy', 'smoke signal'); //结果是:Bob says Howdy with a smoke signal

(2)可选的命名参数

定义函数时,使用{param1, param2, …},放在参数列表的最后面,用于指定命名参数。例如:

//设置[bold]和[hidden]标志
void enableFlags({bool bold, bool hidden}) {
    // ... 
}

调用函数时,可以使用指定命名参数。例如:paramName: value

enableFlags(bold: true, hidden: false);

可选命名参数在Flutter中使用非常多。**注意,不能同时使用可选的位置参数和可选的命名参数。

三、mixin

Dart 是不支持多继承的,但是它支持 mixin,简单来讲 mixin 可以 “组合” 多个类,我们通过一个例子来理解。
定义一个 Person 类,实现吃饭、说话、走路和写代码功能,同时定义一个 Dog 类,实现吃饭、和走路功能:

class Person {
  say() {
    print('say');
  }
}

mixin Eat {
  eat() {
    print('eat');
  }
}

mixin Walk {
  walk() {
    print('walk');
  }
}

mixin Code {
  code() {
    print('key');
  }
}

class Dog with Eat, Walk{}
class Man extends Person with Eat, Walk, Code{}

下一篇:异步线程

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容