Flutter入门(三)Dart基础语法

从上两篇文章中我们对Flutter已经有一个大概的了解,接下来我们从Dart 语法来进一步了解Flutter,我们从以下几个部分来入手:

  • 1.Dart中的变量与常量
  • 2.Dart中的数据类型
  • 3.Dart中的运算符
  • 4.Dart中的方法

1.Dart中的变量常量

1.1 var变量

//变量声明初始化
void varibleFunc() {
  var name;
  print(name);
  name = 'MG';
  print(name);
  name = 1;
  print(name);

  var age = 18;
  print(age);
}

打印结果

flutter: null
flutter: MG
flutter: 1
flutter: 18

说明:

  • 使用var声明一个变量,可以赋值不同的类型
  • var声明的变量如果没有初始化,那么它的值为nil

1.2final 最终变量

//最终变量声明初始化
void finalVariableFunc() {
  final name;
  print(name);
  name = 'MG';
  print(name);
  name = 'xm';
  print(name);
}

此时编译器会报错

  • 使用final声明的一个只能赋值一次的变量
  • 使用final声明的变量在使用之前必须赋值
  • 它是最终变量

1.3const常量

//常量声明初始化
void constanFunc() {
  const name = 'LH';
  print(name);
  //这里再次赋值,编译器会报错
  //name = "MG";
  //print(name);
}
  • 使用const声明的常量在声明时就得赋值
  • 使用const声明的常量赋值后不能修改

如果您从未打算更改变量,可以使用 finalconst 来代替 var 或添加到类型之外。final变量只能设置一次; const变量 是编译时常量。(Const变量 隐式为final。)最终的顶级变量或类变量在第一次使用时进行初始化。

2.Dart中的数据类型

Dart 语言对以下类型有特殊的支持:

  • numbers
  • strings
  • booleans
  • lists
  • sets
  • maps
  • runes
  • symbols

可以使用字面量 初始化这些特殊类型中的任何一个对象。例如,this is a string 是一个字符串字面量,而 true 是一个布尔字面量。

因为 Dart 中的每个变量都指向一个对象(类的实例),所以通常可以使用构造函数来初始化变量。一些内置类型有自己的构造函数。例如,您可以使用 Map() 构造函数来创建映射

2.1num类型

Dartnum有两种,intdouble

//num类型
void numFunc() {
  num i = 2;
  print(i);
  i = 1.1;  //用num声明的变量这里是可以转换类型的
  print(i);

  int a = 1;
  print(a.isEven);  //是否偶数
  print(a.isOdd);   //是否奇数

  double b = 1.12;
  print(b);

  // String -> int
  int one = int.parse('1');
  print(one + 2);  // 输出3

  // String -> double
  var onePointOne = double.parse('1.1');
  print(onePointOne + 2);  // 输出3.1

  // int -> String
  String oneAsString = 1.toString();
  // The argument type 'int' can't be assigned to the parameter type 'String'
  //print(oneAsString + 2);
  // 输出 1 + 2
  print('$oneAsString + 2');
  // 输出 1 2
  print('$oneAsString 2');

  // double -> String 注意括号中要有小数点位数,否则报错
  String piAsString = 3.14159.toStringAsFixed(2);
  print(piAsString);  // 截取两位小数, 输出3.14

  String aString = 1.12618.toStringAsFixed(2);
  // 检查是否四舍五入,输出1.13,发现会做四舍五入
  print(aString);
}
  • num 变量,在使用之前必须赋值
  • num支持运算符 +, -, *, /, %(取模), ~/(取整)
  • num类型的数据也能转换类型 toInt(), toDouble(), toString()

2.2Strings类型

// 关于string 类型测试
void stringFunc() {
  // `Dart字符串` 是由UTF-16编码单元组成的序列。可以使用`单引号`或`双引号`创建字符串:
  var s1 = 'hello';
  var s2 = "flutter";
  var s3 = '我是MG';
  var s4 = 'MG';

  print(s1 + s2); //输出helloflutter
  print(s3*2); //我是MG我是MG

  // 可以使用相邻的字符串字直接连接在一起 或者 `+操作符` 来连接字符串:
  var s5 = 'Flutter_''MG_'"hello";
  assert(s5 ==
      'Flutter_MG_hello');

  // 另一种创建多行字符串的方法是:`使用带有单引号` 或 `双引号的三引号:`
  var s7 = '''
  单引号创建多行字符串 
  注意要各行哦''';
  var s8 = """双引号创建多行字符串  
  注意要各行哦""";
  print(s7);
  print(s8);

  // 单引号或者双引号里面嵌套使用引号。
  // 用 {} 来计算字符串中变量的值,需要注意的是如果是表达式需要${表达式}

  // 单引号嵌套双引号
  String s9 = '$s1 a "MG" ${s3}';
  // 输出 hello a "MG" 我是MG
  print(s9);
  // 双引号嵌套单引号
  String s10 = "${s4.toUpperCase()} abc 'MG' $s4.toUpperCase()";
  // 输出 MG abc 'aaa' MG.toUpperCase(),
  // 可以看出 '$s4.toUpperCase()' 没有加'{}',导致输出结果是'MG.toUpperCase()'
  print(s10);

  String s11 = '这是第一行\n这是第二行';
  String s12 = r'这是第一行\n这是第二行';
  /*输出
   * 这是第一行
   * 这是第二行
   */
  print(s11);
  print(s12); //输出 这是第一行\n这是第二行
  print(s12[1]); //输出 是
}
  • Dart字符串 是由UTF-16编码单元组成的序列。可以使用单引号双引号创建字符串:
  • 创建多行字符串的方法是:使用带有单引号双引号的三引号:
  • {}来计算字符串中变量的值,需要注意的是如果是表达式需要 ${表达式}
  • Dart中字符串的操作是很方便的,可以使用角标的方式获取字符串某个位置上的字符
  • 字符串之间也可以进行+, *运算
  • 在字符串中如果不需要转义那么在字符串前添加r

2.3Bool 类型

为了表示布尔值,Dart有一个名为 bool 的类型。只有两个对象具有 bool类型 : 布尔字面值 truefalse,它们都是编译时常量。因为和我们一般了解一致 这里不做赘述

2.4list类型

//关于list
void listsFunc() {
  //声明一个可变list
  var list1 = [1,2,3];
  //声明一个不可变list
  var list2 = const [1,2,3];
  //list2[1] = 4; // 报错

  //在list中可以存放不同类型的数据
  var list3 = [1, 'name', list2];
  print(list3);

  // spread operator (...)  的用法
  var list4 = [0, ...list1];
  print(list4);  // [0, 1, 2, 3]
  // 注意插入空的情况 那么就需要 `(...?)`
  var list5 ;
  var list6 = [0, ...?list5];
  print(list6);  // [0]

  // list 增删改查
  // 增加元素
  list1.add(4);
  print(list1);       // [1, 2, 3, 4]
  // 删除元素
  list1.remove(4);
  print(list1);    // [1, 2, 3]

  // 修改元素
  list1[1] = 100;
  print(list1);     // [1, 100, 3]
  // 查询
  print(list1.indexOf(3));          // 2 获取元素的下标
  print(list1.elementAt(1));        // 100
  print(list1.contains(666));       // false
}

2.5Map类型

map 是一个关联键和值的对象 (也就是我们所说的字典)

  • map 中的键值对是唯一的
  • map 里面的 value 可以相同
  • map 里面的 value 可以为空字符串
//关于maps
void mapsFunc(){
  //可变map
  var person = {
    // Key:    Value
    'age': 18,
    'name': 'LiHua',
    'hobby': '女',
    'height': 1.85
  };

  //不可变map
  // var student = const {'name', 'zhangsan'};

  print(person); // {age: 18, name: LiHua, hobby: 女, height: 1.85}
  print('${person.keys},${person.values}'); // (age, name, hobby, height),(18, LiHua, 女, 1.85)

  // Map的赋值,中括号中是Key,这里可不是数组
  person['age'] = '20';
  //Map中的键值对是唯一的
  //同Set不同,第二次输入的Key如果存在,Value会覆盖之前的数据
  person['name'] = 'xiaoming';
  // map里面的value可以相同
  person['hobby'] = 'male';
  // map里面value可以为空字符串
  person['hobby'] = '';
  print(person);    // {age: 20, name: xiaoming, hobby: , height: 1.85}
}

3.Dart中的运算符

Dart中有两种特殊的运算符,??=, ??;

//运算符
void operatorFunc() {
  //Dart中有两种特殊的运算符
  //赋值运算 ??=
  //条件表达式 ??

  var a;
  a ??= 10; //如果a为null时则赋值
  a ??= 5; //如果a不为null时则不赋值
  print(a); //输出 10
  
  var b;
  b = 5;
  print(b ?? a); //输出5
  
  var c;
  print(c ?? a); //输出10
  
  // ??如果左边有值返回左边,如果左边没有值则返回右边
}

4.Dart中的方法

  • Dart中的方法也是一个对象
  • Dart方法的返回值和参数类型可以省略
  • Dart方法的执行语句只有一句的时候,可以使用箭头函数 =>

4.1=>箭头函数

//Dart的方法
void functionDemo() {
  print(sum(10, 20));
}

// int sum(int a, int b) {
//   return a + b;
// }
//也可以写成这样,不过不建议这样写
// sum(a, b) => a + b;
//同时 =>函数也可以加入三目运算
sum(a, b) => a == 20 ? a + b : a - b;

4.2Dart方法的可选参数

  • Dart方法中有可选参数并用{}时,传递参数的时候必须带上形参的名字
  • Dart方法中有可选参数并用[]时,传递参数的时候参数的位置时固定的
//Dart的方法
void functionDemo() {
  //必须带上行参的名字(c,b)顺序随意
  print(sum1(10, c: 1, b: 5));
  //b:1 c:5
  print(sum2(10, 1, 5));
}

//sum1(int a, {b, c}) {
//如果需要指定可选参数的类型,可以加上?告诉编译器,后面处理了为空的情况
//sum1(int a, {int? b, int? c}) {
//也可以给可选参数赋默认值
sum1(int a, {int b = 1, int c = 2}) {
  b ??= 0;
  c ??= 0;
  return a - b + c;
}

//给可选参数设定位置,在传参时b和c的位置不能变
sum2(int a, [int b = 1, int c = 2]) {
  return a - b + c;
}

4.3Dart方法做为参数传递

前文中我们提到过Dart方法是一个对象,那么方法也能作为一个参数传递

void functionDemo() {
  var list = [1,2,3,4];
  //print这个方法作为一个参数传入
  forEachFunc(list, print); //输出1,2,3,4
}

forEachFunc(List list, void func(var element)) {
  //在for循环内部调用外部传入的方法
  for (var e in list) func(e);
}

4.4Dart中的匿名函数

匿名方法顾名思义,就是没有方法名称的方法

void functionDemo() {
  var list = [1,2,3,4];
  //匿名函数作为参数
  forEachFunc(list, (var e) {
    e ++;
    print(e);
  }); //输出1,2,3,4
  
  var func = () {
    print('我是一个匿名方法');
  };
  func();
}

forEachFunc(List list, void func(var element)) {
  for (var e in list) func(e);
}

4.5Dart中的闭包closure

  • 闭包:定义在函数里面的函数就是闭包,闭包也是一个对象
  • 闭包的作用:它可以访问外部函数的局部变量

我们通过下面的示例来理解

//Dart中的闭包
void closureDemo() {
  var func = funcA();
  func();
  func();
  func();
  func();
  //输出1,2,3,4
  //funA里的count参数一直被持有

  var func1 = funcA();
  func1();
  func1();
  func1();
  func1();
  //输出 1,2,3,4

}

funcA() {
  int count = 0;
  return ()=>print(count++); //这个匿名函数就是一个闭包
}

最后

大家也可以对照Dart官方文档一起学习

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

推荐阅读更多精彩内容