Dart(二)基础语法

数据类型

Dart中所有东西都是对象,包括数字、函数等
它们都继承自Object,并且默认值都是null(包括数字)因此数字、字符串都可以调用各种方法

Dart中支持以下数据类型:

Numbers
Strings
Booleans
List(也就是数组)
Maps

容器后面再讲,这里先说说常用的字符串和数值类型
还是先建工程吧!Dart代码如下

void main()
{
  //Dart 语言本质上是动态类型语言,类型是可选的
  //可以使用 var 声明变量,也可以使用类型来声明变量
  //一个变量也可以被赋予不同类型的对象
  //但大多数情况,我们不会去改变一个变量的类型
  
  //字符串赋值的时候,可以使用单引号,也可以使用双引号
  var str1 = "Ok?";
  
  //如果使用的是双引号,可以内嵌单引号
  //当然,如果使用的是单引号,可以内嵌双引号,否则需要“\”转义
  //String str2 = ‘It\’s ok!’;
  String str2 = "It's ok!";
  
  //使用三个单引号或者双引号可以多行字符串赋值
  var str3 = """Dart Lang
  Hello,World!""";
  
  //在Dart中,相邻的字符串在编译的时候会自动连接
  //这里发现一个问题,如果多个字符串相邻,中间的字符串不能为空,否则报错
  //但是如果单引号和双引号相邻,即使是空值也不会报错,但相信没有人这么做
  //var name = 'Wang''''Jianfei'; 报错
  var name = 'Wang'' ''Jianfei';
  
  //assert 是语言内置的断言函数,仅在检查模式下有效
  //如果断言失败则程序立刻终止
  assert(name == "Wang Jianfei");
  
  //Dart中字符串不支持“+”操作符,如str1 + str2
  //如果要链接字符串,除了上面诉说,相邻字符串自动连接外
  //还可以使用“$”插入变量的值
  print("Name:$name");
  
  //声明原始字符串,直接在字符串前加字符“r”
  //可以避免“\”的转义作用,在正则表达式里特别有用
  print(r"换行符:\n");
  
  //Dart中数值是num,它有两个子类型:int 和 double
  //int是任意长度的整数,double是双精度浮点数
  var hex = 0xDEADBEEF;
      
  //翻了半天的文档,才找打一个重要的函数:转换进制,英文太不过关了
  //上面提到的字符串插值,还可以插入表达式:${}
  print("整型转换为16进制:$hex —> 0x${hex.toRadixString(16).toUpperCase()}");

}
注:新版本SDK已支持“+”操作符连接字符串

const,final和var的区别

再聊点const和final,用法和其他语言类似
在声明变量的时候,除了var,还可以使用const和final
同时,在使用const和final的时候,可以省略var或者其他类型

var i = 10;
const i = 10;
final i = 10;

int i = 10;
const int i = 10;
final int i = 10;

const和final定义的都是常量,值不能改变
并且在声明的时候就必须初始化
但是也有细微差别,简单来说

const定义的是编译时常量,只能用编译时常量来初始化
final定义的常量可以用变量来初始化
final time = new DateTime.now(); //Ok
const time = new DateTime.now(); //Error,new DateTime.now()不是const常量

var、final等在左边定义变量的时候,并不关心右边是不是常量
但是如果右边用了const,那么不管左边如何,右边都必须是常量

const list = const[1,2,3];//Ok
const list = [1,2,3];//Error

final list = [1,2,3];//Ok
final list = const[1,2,3];//Ok
final list = const[new DateTime.now(),2,3];//Error,const右边必须是常量

函数

1.函数定义

首先,函数也是对象,当没有指定返回值的时候,函数返回null
函数定义方法如下:

String sayHello(String name)
{
  return 'Hello $name!';
}

//is is!操作符判断对象是否为指定类型,如num、String等
assert(sayHello is Function);

断言函数assert(),Debug模式下,当表达式的值为false时抛出异常。
在SDK 1.22.0中,assert()添加了第二个参数message,用于在抛出异常的时候,输出具体信息。

当然,因为Dart中的类型是可选的,也可以这样写

sayHello(name)
{
  return 'Hello $name!';
}

不过建议明确函数的输入类型和返回类型
方便修改,也方便阅读
如果函数只是简单的返回一个表达式的值,可以使用箭头语法 =>expr;
它等价于{return expr;}
所以上面的函数也可以这样写

sayHello(name) => 'Hello $name!';

Dart中匿名函数的写法 (name)=>’Hello $name!’;
于是可以如下定义匿名函数

var  sayHello = (name)=>'Hello $name!';

2.函数别名

当看到用typedef定义函数别名的时候,不自觉的想到了函数指针

typedef int Add(int a, int b);
int Subtract(int a, int b) => a - b;

void main()
{
  print(Substract is Function);
  print(Substract is Add);
}

上面代码的命名感觉有点误导人的感觉
如果两个函数的参数和返回值都一样
那么is操作符就会返回true

3.函数闭包

下面的代码有一点需要注意
初始化变量的时候,参数对应的是函数的参数num n
调用函数类型变量的时候,参数对应的是返回值中的参数num i

Function makeSubstract(num n)
{
  return (num i) => n - i;
}

void main()
{
  var x = makeSubstract(5);
  print(x(2));
}

下面这段很有意思的代码
需要反应过来一件事:Dart中函数也是对象
下面的代码应该看得明白,之后会讲控制语句以及容器

var callbacks = [];
for (var i = 0; i < 3; i++) {
  // 在列表 callbacks 中添加一个函数对象,这个函数会记住 for 循环中当前 i 的值。
  callbacks.add(() => print('Save $i')); 
}
callbacks.forEach((c) => c()); // 分别输出 0 1 2

4.可选参数

Dart中支持两种可选参数:命名可选参数和位置可选参数
但两种可选不能同时使用

    命名可选参数使用大括号{},默认值用冒号:
    位置可选参数使用方括号[],默认值用等号=

在SDK 1.21.0中,允许使用操作符 = 或 : 设置命名可选参数的默认值

在命名可选参数的函数中,大括号外的a为必填参数
大括号内的参数可以指定0个或多个
并且与顺序无关,在调用函数的时候需要指明参数名
没有赋值的参数值为null

FunX(a, {b, c:3, d:4, e})
{
  print('$a $b $c $d $e');
}

在位置可选参数的函数中,大括号内的参数可以指定0个或多个
在调用的时候参数值会依次按顺序赋值

FunY(a, [b, c=3, d=4, e])
{
  print('$a $b $c $d $e');
}


void main()
{
  FunX(1, b:3, d:5);
  FunY(1, 3, 5);
}

操作符和流程控制语句

1、取整

取整~/操作符之前可能很少看到,代码如下:

int a = 3;
int b = 2;
print(a~/b);//输出1

2、级联

当你要对一个单一的对象进行一系列的操作的时候
可以使用级联操作符 ..

class Person {
    String name;
    String country;
    void setCountry(String country){
      this.country = country;
    }
    String toString() => 'Name:$name\nCountry:$country';
}
void main() {
  Person p = new Person();
  p ..name = 'Wang'
    ..setCountry('China');
  print(p);
}

3、If语句

If语句的判断条件为bool值,用法和大多语言一样

if(i<0){
  print('i < 0');
}else if(i ==0){
  print('i = 0');
} else {
  print('i > 0');
}

在checked模式下,如果是非bool值会抛出异常
而在production模式下,非bool值会被翻译成false

if (1) {
  print('JavaScript is ok.');
} else {
  print('Dart in production mode is ok.');
}

在以前出版的书中有段代码

if (?device) { // Returns true if the caller specified the parameter.
//...The user set the value. Do something with it...
}

大概意思是说判断是否传入参数
但试了各种情况,这样写的话都会报错,不知道是不是已经过时的原因
建议判断是否传入参数的时候用 device == null 来替换

4、循环

for(int i = 0; i<3; i++) {
  print(i);
}

如果迭代的对象是容器,那么可以使用forEach或者for-in

var collection = [0, 1, 2];

collection.forEach((x) => print(x));//forEach的参数为Function
for(var x in collection) {
  print(x);
}

另外,while和do-while没有什么变化

while(boolean){
  //do something
}
 
do{
  //do something
} while(boolean)

5、Switch And Case

swith的参数可以是num,或者String

var command = 'OPEN';
switch (command) {
  case 'CLOSED':
    break;
  case 'OPEN':
    break;
  default:
    print('Default');
}

这里有一点要注意,如果分句的内容为空,想要fall-through(落空),可以省略break
如果分句的内容不为空,那么必须加break,否则抛出异常

var command = 'OPEN';
switch (command) {
  case 'CLOSED':
    print('CLOSED');
    break;
  case 'OPEN'://产生落空效果,执行下一分句
  case 'NOW_OPEN':
    print('OPEN');
    break;
  default:
    print('Default');
}

如果你想要fall-through,case语句内容又不为空
而又不是按顺序落空,那么可以使用continue和标签

var command = 'CLOSED';
  switch (command) {
    case 'CLOSED':
      print('CLOSED');
      continue nowClosed; // Continues executing at the nowClosed label.
    case 'OPEN':
      print('OPEN');
      break;
    nowClosed: // Runs for both CLOSED and NOW_CLOSED.
    case 'NOW_CLOSED':
      print('NOW_CLOSED');
      break;
  }

6、异常处理

在Dart中可以抛出非空对象(不仅仅是Exception或Error)作为异常

throw new ExpectException('值必须大于0!');
throw '值必须大于0!';

你可以抛出多个类型的Exception,但是由第一个catch到的分句来处理
如果catch分句没有指定类型,那么它可以处理任何类型的异常

try {
      throw 'This a Exception!';
  } on Exception catch(e) {
    print('Unknown exception: $e');
  } catch(e) {
    print('Unknown type: $e');
  }

无论是否发生异常,为了使某些代码得以运行,可以使用finally语句

try {
      throw 'This a Exception!';
  } catch(e) {//可以试试删除catch语句,只用try...finally是什么效果
    print('Catch Exception: $e');
  } finally {
    print('Close');
  }

你可能感兴趣的:(Dart(二)基础语法)