【Dart】Dart基本语法(一)

一、Dart介绍和安装

1.1. 认识Dart

Flutter的实现是基于Dart语言的,学习一门新的语言,主要是学习他的语法。Dart的语法对前端开发更友好一些,但如果仅有iOS或Android开发经验,学习Dart的时候其实也能够很快上手。之前有Java、Swift、Objective-C、C++、React、Vue等开发经验的同学,会在Dart中看到很多你熟悉的影子,因为Dart借鉴了各种语言的特性,甚至有点像大杂烩。

1.2. 安装Dart

如果仅仅是单独学习和运行Dart,我们需要安装Dart SDK。但在正常开发Flutter项目时是不需要安装的,因为在安装Flutter SDK的时候,已经内置了Dart SDK

下载Dart SDK(安装方式参照官网即可):https://dart.dev/get-dart

1.3. 开发工具配置

VSCode建议安装的三个插件:Dart、Flutter、Code Runner

  • Dart:为编写Dart代码提供支持;
  • Flutter:编写Flutter的环境支持;
  • Code Runner:运行和调试Flutter代码使用

Android Studio建议安装两个插件:Dart、Flutter

二、体验Dart

新建一个helloworld.dart文件,添加下面的内容:

1
2
3
main(List<String> args) {
print('Hello World');
}

终端:dart helloworld.dart,就能看到执行结果了。

从上面一个简单的main函数即可看出Dart和大部分语言一样都需要一个入口main函数,在函数体内即可执行相关代码;同时每个语句结束也是以分号结尾。

三. 定义变量

3.1. 明确声明

格式:

1
变量类型 变量名称 = 赋值;

示例:

1
2
3
String name = 'idbeny';
int age = 28;
double height = 1.80;

注意事项: 已经定义的变量可以修改值, 但是不能赋值其他类型

1
2
3
String name = 'idbeny';
content = '1024星球'; // 正确的
content = 1234; // 错误的, 将一个int值赋值给一个String变量

以上代码中,变量name已经指定为字符串类型了,这时候如果修改name为其他字符串类型是可以的,如果赋值其他类型(如浮点型、整形)就会报错。

3.2. 类型推导

格式:

1
2
3
4
var 变量名称 = 赋值;
dynamic 变量名称 = 赋值;
const 变量名称 = 赋值;
final 变量名称 = 赋值;
3.2.1. var的使用

示例:

1
2
3
var name = 'idbeny';
name = '1024星球';
print(name.runtimeType); // String

错误用法:

1
2
var age = 28;
age = 'idbeny'; // 不能把String赋值给一个int类型
  • 因为变量在初始化的时候已经确定了该变量的类型,所以在后续使用的时候是不能再赋值其他类型的。
  • 用var修饰的变量不能赋值不同类型的值,但是可以使用dynamic来修饰。
3.2.2. dynamic的使用

示例:

1
2
3
4
dynamic name = 'idbeny';
print(name.runtimeType); // String
name = 28;
print(name.runtimeType); // int

dynamic在开发中也会经常遇到,但建议谨慎使用,因为是运行时判断,所以会引发一些未知的错误

3.2.3. final和const的使用

final和const都是用于定义常量的(定义之后值都不可以修改)

1
2
3
4
5
final name = 'idbeny';
name = '1024星球'; // 错误做法

const age = 28;
age = 18; // 错误做法

final和const的区别?

  • const在赋值时, 赋值的内容必须是在编译期间就确定下来的;

  • final在赋值时, 可以动态获取, 但是final一旦被赋值后就有确定的结果, 不会再次赋值;

    1
    2
    3
    4
    main(List<String> args) {
    // const time = DateTime.now(); // 错误的赋值方式
    final time = DateTime.now();
    }
  • const可以修饰创建的对象。

四、数据类型

4.1. 数字类型(int/double)

整形和浮点型

1
2
3
4
5
int age = 28; // 整形
print(age);

double height = 1.80; // 浮点型
print(height);

字符串和数字之间的转化:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 1.字符串转数字
var num1 = int.parse('1234');
var num2 = double.parse('12.34');
print('${num1} ${num1.runtimeType}'); // 1234 int
print('${num2} ${num2.runtimeType}'); // 12.34 double

// 2.数字转字符串
var num1 = 1234;
var num2 = 12.345;
var num1Str = num1.toString();
var num2Str = num2.toString();
var num2PointStr = num2.toStringAsFixed(2); // 保留两位小数
print('$num1Str ${num1Str.runtimeType}'); // 1234 String
print('$num2Str ${num2Str.runtimeType}'); // 12.345 String
print('$num2PointStr ${num2PointStr.runtimeType}'); // 12.35 String

4.2. 布尔类型(Bool)

布尔类型中,Dart提供了一个bool的类型, 取值为true和false

1
2
var isFlag = true;
print('$isFlag ${isFlag.runtimeType}'); // true bool

注意: Dart中不能判断非0即真, 或者非空即真

1
2
3
4
var name = 'idbeny';
if (name) { // name不会打印
print(name);
}

4.3. 字符串类型(String)

创建一个字符串:单引号或双引号

1
2
3
var s1 = 'Hello World';
var s4 = "Hello'World";
var s2 = "idbeny";

多行字符串:三个单引号或者双引号

1
2
3
4
var message1 = '''
你好啊
很高兴
认识你''';

4.4. 集合类型(List/Set/Map)

List

1
2
3
4
5
// 1.类型推导
var words = ['a', 'b', 'c', 'd'];

// 2.明确类型
List<int> numbers = [1, 2, 3, 4];

Set

1
2
3
4
5
// 1.类型推导
var words = {'a', 'b', 'c', 'd'};

// 2.明确类型
Set<int> numbers = {1, 2, 3, 4};
  • Set和List最大的区别:Set是无序的,并且元素是不重复的。
  • 常见操作
    • length(获取集合的长度)
    • add(添加元素)
    • remove(移除元素)
    • contains(包含元素)
    • removeAt(根据索引未知删除元素–List持有,Set没有)
      1
      2
      3
      4
      5
      numbers.length;
      numbers.add(1);
      numbers.remove(1);
      numbers.contains(1);
      numbers.removeAt(1);

Map(字典)

1
2
3
4
5
// 1.类型推导
var person = {'name': 'idbeny', 'age': 28};

// 2.明确类型
Map<String, Object> map = {'name': 'idbeny', 'address': 'www.idbeny.com', 'age': 28};
  • 常见操作
    • 根据key获取value map['name']
    • 获取所有的entries map.entries
    • 获取所有的keys map.keys
    • 获取所有的values map.values
    • 判断是否包含某个key或者value map.containsKey('name'); map.containsValue(28)
    • 根据key删除元素 map.remove('name')

五、函数

5.1. 函数的定义

Dart是面向对象语言,函数也是对象,所有也有类型, 类型就是Function,并且函数可以作为变量定义或者作为其他函数的参数或者返回值使用。

格式:

1
2
3
4
返回值 函数的名称(参数列表) {
函数体
return 返回值;
}

示例:

1
2
3
int sum(num num1, num num2) {
return num1 + num2;
}
  • 如果我们省略函数返回类型,函数依然是可以运行的,但是如果是公共函数,建议把类型加上
  • 如果函数中只有一个表达式, 那么可以使用箭头函数
  • 注意, 这里面只能是一个表达式, 不能是一个语句
    1
    sum(num1, num2) => num1 + num2;

5.2. 函数的参数

参数(必传和可选)
  • 位置可选参数:使用中括号包裹
    1
    2
    3
    4
    5
    6
    7
    8
    // 格式:位置可选参数: [param1, param2, ...]

    // 示例:
    Person(String name, [int age, double height]) {
    print('name=$name age=$age height=$height');
    }
    Person('idbeny', 28);
    Person('idbeny', 28, 1.80);
  • 命名可选参数:使用大括号包裹。可以指定某个参数是必传的(使用@required)
    1
    2
    3
    4
    5
    6
    7
    // 格式:{param1, param2, ...}

    // 示例:
    Person(String name, {int age, double height, @required String address}) {
    print('name=$name age=$age height=$height address=$address');
    }
    Person('idbeny', age: 28, address: 'www.idbeny.com');
默认值

只有可选参数才可以有默认值, 必传参数不能有默认值

1
2
3
4
// 参数的默认值
Person(String name, {int age = 28, String address="www.idbeny.com"}) {
print('name=$name age=$age address=$address');
}

5.3. 匿名函数

JS中有匿名函数,Dart其实也是支持匿名函数的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
main(List<String> args) {
var words = ['aaa', 'bbb', 'ccc', 'ddd'];

// 有名字的函数
readWords(item) {
print(item);
}
words.forEach(readWords);

// 匿名函数
words.forEach((item) {
print(item);
});
words.forEach((item) => print(item));
}

5.4. 作用域

  • Dart是根据代码的结构({})来决定作用域范围的
  • 和大部分语言类似,优先使用自己作用域中的变量,如果没有找到,则一级级向外查找。

补充

  • runtimeType:获取变量当前的类型;

    1
    2
    final name = 'idbeny';
    print(name.runtimeType); // String
  • identical:比较两个对象是否相同;

    1
    2
    3
    final p1 = Person();
    final p2 = Person();
    print(identical(p1, p2)); // false
  • ${expression}:字符串拼接,如果只是一个标识符,不需要加{},如果是表达式,则必须加{};

    1
    2
    3
    4
    final name = 'idbeny';
    final age = 28;
    print('${name} ${name.runtimeType}'); // idbeny String
    print('$age ${age.runtimeType}'); // 28 int