Dart语法学习


最近在学习flutter相关方面的知识,里面用到了Dart语言,于是写下这篇博客记录学习的一门过程。如果你有其他编程语言的经验(尤其是Java和JavaScript),可以很快的上手Dart语言,Dart 在设计时应该是同时借鉴了 Java 和 JavaScript,同时又引入了一些现代编程语言的特性,如空安全,除此之外还有一些独创的语法,比如级联操作符。总之,熟悉之后,你会发现 Dart 是一门非常有意思的编程语言 !
选择的编译工具为vscode,在vscode扩展中安装flutter和coder runner插件,之后便可以运行dart语言
例如:

void main(List<String> args) {

  var name = "zhangsan";

  print(name);

}
//输出为zhangsan

![[Pasted image 20230529151412.png]]

1.特殊关键字

变量是一个引用,在dart语言中具有“:万物皆对象的原则,即变量存储的都是对象的引用,或者说是它们指向对象。

1.1 不指定数据类型,即使用var关键字(类似与JavaScript)

 var name = 'John';

1.2 指定数据类型

String name = 'John';
//因为有类型推导,所以两种实现效果一样,官方推荐在函数内的本地变量尽量使用var声明。

1.3 默认值

未初始化的变量默认值是 null。即使变量是数字类型默认值也是 null,因为在 Dart 中一切都是对象,数字类型也不例外。

int lineCount;//默认为空
assert(lineCount == null);//true

1.4 final和const关键字

使用过程中从来不会被修改的变量, 可以使用 final 或 const,而不是 var 或者其他类型,Final 变量的值只能被设置一次; Const 变量在编译时就已经固定 (Const 变量 是隐式 Final 的类型) 。最高级 final 变量或类变量在第一次使用时被初始化。

  • Const关键字主要用于声明和创建常量。例如:
 const bar = 1000000; // 压力单位 (dynes/cm2)
 const double atm = 1.01325 * bar; // 标准气压
  • final关键字
final name = 'Bob'; // Without a type annotation
final String nickname = 'Bobby';
name = 'Alice'; // Error: 一个 final 变量只能被设置一次。

2. 常见数据类型

Dart 语言有以下的数据类型:

  • Number
  • String
  • Boolean
  • List (也被称为 Array)
  • Map
  • Set
  • Rune (用于在字符串中表示 Unicode 字符)
  • Symbol

2.1 Number

number有两种数据类型

  • int(整型)
  • double(双精度浮点数)

int 和 double 都是 num. 的亚类型。 num 类型包括基本运算 +, -, /, 和 *, 以及 abs(), ceil(), 和 floor(), 等函数方法。 (按位运算符,例如»,定义在 int 类中。) 如果 num 及其亚类型找不到你想要的方法, 尝试查找使用 dart:math 库。

double x = 1; 相当于 double z = 1.0.
int x  = 0;

数据类型之间的相互转换(类似于Java语言)

// String -> int
var one = int.parse('1'); assert(one == 1); // String -> double 
var onePointOne = double.parse('1.1'); assert(onePointOne == 1.1); 
// int -> String 
String oneAsString = 1.toString(); assert(oneAsString == '1'); 
// double -> String 
String piAsString = 3.14159.toStringAsFixed(2); assert(piAsString == '3.14');


2.2 string数据类型

Dart 字符串是一组 UTF-16 单元序列。 字符串通过单引号或者双引号创建。

var s1 = 'Single quotes work well for string literals.';

字符串可以通过 ${expression} 的方式内嵌表达式。 如果表达式是一个标识符,则 {} 可以省略。 在 Dart 中通过调用就对象的 toString() 方法来得到对象相应的字符串。

var s = 'string interpolation';
assert('Dart has $s, which is very handy.' == 'Dart has string interpolation, ' + 'which is very handy.'); //用$s来引用字符串s
assert('That deserves all caps. ' + '${s.toUpperCase()} is very handy!' == 'That deserves all caps. ' + 'STRING INTERPOLATION is very handy!');//引用字符串s并调整为大写字母

  • 同时, == 运算符用来测试两个对象是否相等,可以使用 + 运算符来把多个字符串连接为一个。

2.3 Boolean数据类型

Dart使用bool类型标识布尔值。Dart只有字面量true和false。

// 检查空字符串。
var fullName = ''; 
assert(fullName.isEmpty);

2.4 List数据类型

Dart中的List字面量和Java的arry类型相类似,例如:

var list = [1, 2, 3];
assert(list.length == 3); 
assert(list[1] == 2);
list[1] = 1;
assert(list[1] == 1);

// 往list里面添加数据
 var test = [];
 test.add(1);

2.5 set集合

在 Dart 中 Set 是一个元素唯一且无序的集合。 Dart 为 Set 提供了 Set 字面量和 Set 类型。下面为创建set集合的实例:

var halogens = {'fluorine', 'chlorine', 'bromine', 'iodine', 'astatine'};//指定固定的几个元素
var elements = <String>{};//未指定大小
elements.add('fluorine'); elements.addAll(halogens);
assert(elements.length == 5);//获取长度

2.6 Map集合

通常来说, Map 是用来关联 keys 和 values 的对象。 keys 和 values 可以是任何类型的对象。在一个 Map 对象中一个 key 只能出现一次。 但是 value 可以出现多次。 Dart 中 Map 通过 Map 字面量 和 Map 类型来实现。
简单例子:

var gifts = { 
// Key: Value 
'first': 'partridge', 'second': 'turtledoves', 'fifth': 'golden rings' }; 
var nobleGases = {
2: 'helium', 
10: 'neon',
18: 'argon', };

也可以使用Map构造函数来创建

var gifts = Map();
gifts['first'] = 'partridge'; //相当于添加元素
gifts['second'] = 'turtledoves';
gifts['fifth'] = 'golden rings'; 
var nobleGases = Map(); 
nobleGases[2] = 'helium'; 
nobleGases[10] = 'neon';
nobleGases[18] = 'argon';

查找

var gifts = {'first': 'partridge'}; assert(gifts['first'] == 'partridge');//查找键值对
var gifts = {'first': 'partridge'};//查看key是否存在
assert(gifts['fifth'] == null);

3. 函数

3.1 函数声明

  • 直接声明
// 直接声明
void printMsg() {
  print("hello the world");
}
// 返回值与函数声明的类型要保持一致
String getNum(int num) {
  return 'Age is $num';

}
void main(List<String> args) {
  // 调用函数
  print(getNum(18)); // Age 18
  printMsg();
}
  • 匿名函数
    多数函数是有名字的, 比如 main() 和 printElement()。 也可以创建没有名字的函数,这种函数被称为 匿名函数, 有时候也被称为 lambda 或者 closure 。
var list = ['apples', 'bananas', 'oranges']; list.forEach((item) { print('${list.indexOf(item)}: $item'); });
// 如果函数只有一条语句, 可以使用箭头简写。
list.forEach( (item) => print('${list.indexOf(item)}: $item'));
  • 立即执行函数
  ((int n) {
    print(n);
  }(55)); // 55

3.2 函数参数

  • 必填参数
    参数类型 参数名称 如:int age
  // 必填参数
  int getAge(int age) {
    return age;
  }
  • 可选参数
    1. 放在必填参数后面
    2. 通过 中括号 包起来
    3. 带默认值的可选参数
    ![[Pasted image 20230529162256.png]]
//解决方案一

String getNum(int age, [String name = "zhangsan"]) {
  return 'Age is $age';
}

//解决方案二
String getNum1(int age, [dynamic name]) {
  return 'Age is $age and his name is $name';
}
  • 命名参数
    1. 用 大括号 包起来
    2. 调用函数时,命名参数的名称与声明函数中的名称保持一致
  // 命名参数
  String getScore(String subject, {double score = 0}) {
    return '科目:$subject,分数:$score';
  }
  String math = getScore('数学', score: 123);//score与函数参数里面的名称一样
  print(math); // 科目:数学,分数:123.0

3.3 main()函数

相当于Java的主函数,一个Java类必须要有主函数才能启动,任何应用都必须有一个顶级 main() 函数,作为应用服务的入口。 main() 函数返回值为空,参数为一个可选的 List<String>


void main(List<String> args) {
  // 调用函数
}

4. 控制流程语句

dart语言的流程控制语句和Java语言相类似,主要有以下一些控制语句。

  • if and else
  • for loops
  • while and do-while loops
  • break and continue
  • switch and case
  • assert

4.1 if - else语句


if (isRaining()) { 
	you.bringRainCoat();
} else if (isSnowing()) {
you.wearJacket(); 
} else { 
car.putTopDown();
}

4.2 for 循环语句

进行迭代操作

var message = StringBuffer('Dart is fun'); 
for (var i = 0; i < 5; i++) {
	message.write('!'); 
}

foreach迭代操作

var collection = [0, 1, 2]; 
for (var x in collection) {
print(x); // 0 1 2 
}

4.3 while和do-while语句

while循环在执行前判断执行条件

while (!isDone()) { doSomething(); }

do-while循环在执行后判断执行条件

do{
	printLine();
	
}while(!atEndOfPage());

4.4 beak 和continue语句

使用break停止程序循环

while (true) { 
		if (shutDownRequested()) break;    processIncomingRequests();
	 }

使用continue跳转到下一次迭代

for (int i = 0; i < candidates.length; i++) {
var candidate = candidates[i];
if (candidate.yearsExperience < 5) { 
continue; 
}
}

4.5 switch与case

在 case 语句中,每个非空的 case 语句结尾需要跟一个 break 语句。 除 break 以外,还有可以使用 continue, throw,者 return。

当没有 case 语句匹配时,执行 default 代码:

var command = 'OPEN'; 
switch (command) {
case 'CLOSED':executeClosed();break;
case 'PENDING': executePending(); break; 
case 'APPROVED': executeApproved(); break;
case 'DENIED': executeDenied(); break;
case 'OPEN': executeOpen(); break; default: executeUnknown();
}

4.6 assert语句

如果 assert 语句中的布尔条件为 false , 那么正常的程序执行流程会被中断

// 确认变量值不为空。 
assert(text != null); // 确认变量值小于100。 
assert(number < 100); // 确认 URL 是否是 https 类型。
assert(urlString.startsWith('https'));

5.异常

Dart 代码可以抛出和捕获异常。 异常表示一些未知的错误情况。 如果异常没有被捕获, 则异常会抛出, 导致抛出异常的代码终止执行。

和 Java 有所不同, Dart 中的所有异常是非检查异常。 方法不会声明它们抛出的异常, 也不要求捕获任何异常。(就是如果没有主动抛出异常或者捕获异常,在编写代码时不会报错,但是会在运行的过程中报错)

Dart 提供了 Exception 和 Error 类型, 以及一些子类型。 当然也可以定义自己的异常类型。 但是,此外 Dart 程序可以抛出任何非 null 对象, 不仅限 Exception 和 Error 对象。

5.1 throw

下面是关于抛出或者 引发 异常的示例:

throw FormatException('Expected at least 1 section');

也可以抛出任意的对象

throw 'Out of llamas!';

5.2 try catch

捕获异常可以避免异常继续传递(除非重新抛出( rethrow )异常)。 可以通过捕获异常的机会来处理该异常:

try { breedMoreLlamas(); } on OutOfLlamasException { // 一个特殊的异常 
buyMoreLlamas();
} on Exception catch (e) { // 其他任何异常,只捕捉指定类型的异常 
print('Unknown exception: $e');
} catch (e) { // 没有指定的类型,处理所有异常 
print('Something really unknown: $e'); }

5.3 finally

不管是否抛出异常, finally 中的代码都会被执行。 如果 catch 没有匹配到异常, 异常会在 finally 执行完成后,再次被抛出:

try { breedMoreLlamas(); } finally { // Always clean up, even if an exception is thrown. 
cleanLlamaStalls(); 
}

//任何匹配的catch执行完成后都要执行finally语句:
try { breedMoreLlamas(); 
	} catch (e) { 
	print('Error: $e'); // Handle the exception first. 
	} finally {
	 cleanLlamaStalls(); 
	// Then clean up. 
	}

6. 类

6.1 实例变量

所有实例变量都生成隐式 getter 方法。

class Point {
  num x = 0; // 声明示例变量 x,初始值为 0 。
  num y = 0; // 声明示例变量 y,初始值为 0 。
  num z = 0; // 声明示例变量 z,初始值为 0 。
}
void main(List<String> args) {
  // 调用函数
  var point = Point();
  point.x = 4;
  print(point.x == 4);// true
}

6.2 构造函数

通过创建一个与其类同名的函数来声明构造函数

在没有声明构造函数的情况下, Dart 会提供一个默认的构造函数。

class Point {
  int x = 0, y = 0; //必须进行初始化
  Point(num x, num y) {
    this.x = x;
    this.y = y;
  }
  //或者采用下面的方法
  // Point(this.x, this.y);
}

6.3 继承

继承通过extends关键字实现,默认情况下,子类的构造函数会自动调用父类的默认构造函数(匿名,无参数)。

class Father {
  String name = "zhangsan";
  void sayName() {
    print(name);
  }
}
class Son extends Father {
  void sayName() {
    super.sayName();//调用父类方法
  }
}
void main(List<String> args) {
  var son = Son();
  son.sayName(); // zhangsan
}

6.4 抽象类(与Java一样)

使用 abstract 修饰符来定义 抽象类 — 抽象类不能实例化。 抽象类通常用来定义接口,以及部分实现。 如果希望抽象类能够被实例化,那么可以通过定义一个 工厂构造函数 来实现。

抽象类通常具有 抽象方法。 下面是一个声明具有抽象方法的抽象类示例:

// 这个类被定义为抽象类, 
// 所以不能被实例化。 
abstract class AbstractContainer { // 定义构造行数,字段,方法... 
void updateChildren(); // 抽象方法。 
}

抽象类的一些特性:

  • 抽象类不能实例化,只能单继承。
  • 抽象类可以有抽象方法,只需声明,无需实现
  • 有抽象方法的类一定是抽象类
  • 抽象类的子类必须实现抽象类中的抽象方法,否则子类仍然是抽象类。(实现了就不是抽象类)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值