Flutter Dart 语言基础详解

作者: 不正经的创作者 | 来源:发表于2020-05-06 16:44 被阅读0次

变量

变量的声明

1.var
2.dynamic
3.Object

  • 声明一个未初始化的变量,变量的类型可以更改
  //变量
  /// 三斜杠文档注释
  /// 返回类型 void 可以省略,省略后的返回值为 null

  void main(){
    ///----------------------- 变量的声明-----------------
    ///声明一个未初始化的变量,变量的类型可改变
    var data;
    data = "HelloWorld";

    dynamic data1;
    data1 = "HelloWorld1";
    data1 = 123;

    Object data2;
    data2 = 'HelloWorld2';
    data2 = 123;
    print([data,data1,data2]);
  }

  /// 打印效果
  lib/1-variables.dart:1: Warning: Interpreting this as package URI, 'package:flutter_test3/1-variables.dart'.
  [HelloWorld, 123, 123]

  • 声明一个初始化的变量,变量类型不能再更改
   var variablel =
        'HelloWorld'; //变量是一个引用,名字为 variablel 的变量引用了一个内容为‘HelloWorld’的 String 对象。
   //  variablel = 123; //变量初始化后,variablel 变量的类型被推断为String类型,其类型不能再改变
  • dynamic 和 Object 声明的变量初始化后,变量的类型仍可改变
  dynamic variable2 = "HelloWorld";
    variable2 = 123;
  //  variable2.test();//调用不存在的test()方法,编译通过,运行报异常。编译阶段不检查类型

    Object variable3 = 'HelloWorld';
    variable3 = 123;
  //  variable3.test();//调用不存在的test()方法,编译不通过。编译阶段检查类型
  • 使用确定类型显示声明变量,变量的类型不能再改变
  String name3 = "HelloWorld";
  //  name3 =123; //变量的类型不能更改

变量声明总结
1.var: 如果没有初始值,可以变成任何类型

2.dynamic:动态任意类型,编译阶段不检查类型

3.Object 动态任意类型,编译阶段检查类型

  • 区别:唯一区别 var 如果有初始值,类型被是锁定

默认值

  • 没有初始化的变量默认值都是null

    一切皆对象,对象的默认值是null

  bool isEmpty;
  print((isEmpty == null));

final 和 const

  • 被 final 或者 const 修饰的变量,变量类型可以省略
   final FVariablel = "HelloWorld";
  //  final  String FVariablel = "HelloWorld";

    const cVariablel = "HelloWorld";
  //  const String cVariablel = "HelloWorld";
  • 被 final 或 const 修饰的变量无法再去修改其值。
  //   fVariable1 = '123';
  //   cVariable1 = '123456';
  • 如果是类级别常量,使用 static, const 。
  DateTime; //可参照DateTime static const int monday = 1;
  • const 可以使用其他 const 常量的值来初始化其值.
  const width = 100;
  const height = 100;
  const square = width * height;
  • const 赋值申明可省略
  const List clist = [1, 2, 3];
  //  const List clist = const [1, 2, 3];//dart 2之前,const赋值必须用const声明
  print("\n\n\n");
  print(clist);
  • 可以更改非 final,非 const 变量的值,即使它曾经具有 const 值
  var varList = const [1, 2, 3];
    final finalList = const [1, 2, 3];
    const constList = [1, 2, 3];
    print([varList, finalList, constList]);
    varList = [1];
  //  constList[1];
  //  finalList[1];
    print("\n\n");
    print([varList, finalList, constList]);

      打印效果--
    /***
     * [[1, 2, 3], [1, 2, 3], [1, 2, 3]]
     * [[1], [1, 2, 3], [1, 2, 3]]
     */

  • const 导致的不可变性是可传递的
  final List ls = [1, 2, 3];
    ls[2] = 444;
    print(ls);
    const List cLs = [4, 5, 6];
  //  cLs[1] = 4;
    print("\n");
    print(ls);

  报错:
        /***
     * Unhandled exception:
        Unsupported operation: Cannot modify an unmodifiable list
        #0      UnmodifiableListBase.[]= (dart:_internal/list.dart:90:5)
        #1      main (package:flutter_test3/1-variables.dart:103:6)
     */
  • 相同的 const 常量不会在内存中重复创建
  final finalList1 = [1, 2, 3];
  final finalList2 = [4, 5, 6];
  print("\n");
  print(identical(finalList1, finalList2)); //identical用于检查两个引用是否指向同一个对象

  const constList1 = [1, 2];
  const constList2 = [1, 2];
  print("\n");
  print(identical(constList1, constList2)); //identical用于检查两个引用是否指向同一个对象
  • const 需要是编译时常量
  final DateTime finalDateTime = DateTime.now();
  //    const DateTime constDateTime = DateTime.now();//DateTime.now() 是运行期计算出来的值
    const sum = 1 + 2; //使用内置数据类型的字面量通过基本运算得到的值
    const aConstNum = 0;
    const aConstBool = true;
    const aConstString = 'a constant string';
    const aConstNull = null;
    const validConstString =
        '$aConstNum, $aConstBool, $aConstString, $aConstNull';
    print(validConstString); //使用计算结果为null或数字,字符串或布尔值的编译时常量的插值表达式

final 和 const 总结

共同点

  • 声明的类型可省略
  • 初始化后不能再赋值
  • 不能和 var 同时使用

区别(需要注意的地方)

  • 类级别常量,使用 static ,const 。
  • const 可使用其他 const 常量的值来初始化其值
  • const 可使用其他 const 常量的值来初始化其值
  • 可以更改非 final、非 const 变量的值,即使曾经具有 const 值
  • const 导致的不可变性是可传递的
  • 相同的 const 常量不会在内存中重复创建
  • const 需要是编译时常量

内置类型

Number 数值(num,int,double)

  int i = 1; //整数型
 double d = 1.0 ;//double b4-bit(双精度)浮点数
  int bitLength = i.bitLength;
  print('bitLength:${bitLength}'); //bitLength 判断 int 值需要多少位 bit 位。
  double maxFinite = double.maxFinite;
  print('maxFinite: ${maxFinite}'); //maxFinitedouble的最大值
  //int和double都是num的子类
  num n1 = 1;
  num n2 = 1.0;
  //支持 十进制、十六进制
  int il = oxfff;
  //科学计数法
  double dl = 1.2e2; //120.0
  //转换
  //String > int
  int i2 = int.pasrse('1');
  double d2 = 1;//当 double 的值为 int 值时,int 自动转为 double
  print('d2:${d2}');
  int i2 = int.try.parse('1.0');//返回 null

  //int > String
  int is = 123;
  String s = 123.toString;

String 字符串

  //Dart 字符串是 UTF-16 编码的字符序列,可以使用单引号或者双引号来创建字符串
  var name = 'HelloWorld';
  //可以在字符串中使用表达式: ${expression},如果表达式是一个标识符,可以省略 {}。 如果表达式的结 
 果为一个对象,则 Dart 会调用对象的 toString() 函数来获取一个字符串
  var names = 'HelloWorld ${name}';
  //r 前缀可以创建一个 “原始 raw” 字符串
  var rawNames = r"HelloWorld ${name}";
  print('name:${names}');
  print('rawNames :${rawNames}');
  //如果表达式的结果为一个对象,则 Dart 会调用对象的 toString() 函数来获取一个字符串。
  pint(Map);
  //可以使用三个单引号或者双引号也可以 创建多行字符串对象
  var multiLinesString = '''
  Java Android
  Flutter''';
  pint('mutiLinesString:${mutiLinesString}');

  /// StringBuffer
  var sb = StringBuffer(); //dart 2 可以省略 new
  sb..write('aaa')..write('bbb')..write('ccc');//..级联符实现链式调用
  sb.writeAll([aaa,bbb,ccc],',');//第二个参数表示分隔符,将第一个参数列表里的数据用这个分隔符拼接起来
  pint('sb:${sb}');

Booleans 布尔值 (bool)

  //bool :true 和 false
  bool isNull;
  print('isNull: ${isNull}');

List 列表(数组 List)

  //声明一个自动长度的数组
  List growableList = new List();
  //List growbleList = new List()..length = 3;
  growbleList..add(1)..add(2)..add('HelloWorld');
  pint('growbleList: ${growbleList}');

  //声明一个固定长度的数组
  var list = List(6);// 这里可以用 var 声明,也可以用 List
  list[0] = "Java";
  list[1] = "Android";
  list[2] = "Dart";
  list[3] = "Flutter";
  list[4] = "C++";
  list[5] = "C"
  pint('list:${list}');

  //元素固定类型
  var typeList = List<String>;
  typeList..add("1")..add("2")..add("3");
  pint('typeList:${typeList}');

  //常用属性-获取第一个元素
  String first = typeList.fisrt;
  pint('typeList.fisrt:$typeFirst');
  //最后一个元素
  String last = typeList.last;
  pint('typeList.last:${last}');
  //元素个数
  int typeListLength = typeList.length;
  pint('typeListLength:${typeListLength}');
  //元素是否为空
  bool isEmpty = typeList.isEmpty;
  pint('typeList.isEmpty:${isEmpty}');
  //元素是否不为空
  bool isNotEmpty = typeList.isNotEmpty;
  pint('typeList.isNotEmpty:${isNotEmpty}');
  //数组倒序
  Iterable reversed = typeList.reversed;
  print('typeList.reversed:${reversed}');

  // 常用方法 增删改查,排序,洗牌,复制子列表
  var list4 = [];
  //增
  list4.add(1);
  pint('add 1:${list4}');
  list4.addAll([2,3,4]);
  print('addAll[2,3,4]:${list4}');
  list4.insert(0,0);
  print('insert(0,0) : ${list4}');
  list4.insertAll(1,[5,6,7,8]);
  print('insertAll(1,[5,6,7,8]) :${list4}');
  //删除
  list4.remove(5);
  print('remove 5 :${list4}');
  list4.removeAt(2);
  print('remove at 0:${list4}');
  //改
  list4[4] = 5;
  print('updata list4[4] to 5 :${list4}');
  //range
  list4.fillRange(0,3,9);
  print('fillRange updata list4[0] - list[2] to 9 :$list4');
  Iterable getRange = list4.getRange(0,3);
  print('getRange list4[0]-list[2]:${getRange}');
  //查
  var contains = list.contains(5);
  print('contains 5 :${contains}');
  var indexOf = list4.indexOf(1);
  print('list4 indexOf 1 :${indexOf}');
  int indexWhere = list4.indexWhere((test) => test == 5);
  print('list4 indexWhere 5 :${indexWhere}');
  // 排序
  list4.sort();
  print('list4 sort:${list4}');
  //洗牌
  list4.shuffle();
  print('list4 shuffle:${list4}');
  //复制子列表
  var list5 = list4.shulist(1);
  print('sublist(1) list5: ${list5}');
  //操作符
  var list6 =[8,9];
  print('list6:${list6}');
  var list7 = list5 + list7;
  print('list5 + list6:${list7}');

Maps 键值对集合 (Map)

  //声明一个动态类型的 Map
  var dynamicMap = Map();
  dynamicMap['name'] = 'HelloWorld';
  dynamicMap[1] = 'android';
  print('dynamicMap :${dymaicMap}');
  //强类型
  var map = Map<int,String>();
  map[1] = 'java';
  map[2] = 'Android';
  print('map :${map}');
  //也可以这样声明
  var map1 = {'name':'Java',1:'android'};
  map1.addAll({'name','Flutter'});
  print('map1:${map1}');
    //常用属性
  //  print(map.isEmpty); //是否为空
  //  print(map.isNotEmpty); //是否不为空
  //  print(map.length); //键值对个数
  //  print(map.keys); //key 集合
  //  print(map.values); //value集合    

Set 集合 (Set)

  // Set 无重复列表
  var dynamicSet = Set();
  dynamicSet.add('java');
  dynamicSet.add('Android');
  dynamicSet.add('Flutter');
  dynamicSet.add('C/C++');
  dynamicSet.add('1');
  dynamicSet.add('1');
  print('dynamicSet :${dynamicSet}');

  //常用属性与 List 类似
  //常用方法 增删改查与 List 类似
  var set1 = {'java','Android'};
  print('set1: ${set1}');
  var differencel2 = set1.difference(set2);
  var difference21 = set1.difference(set1);
  print('set1 difference set2 :${differencel2}');//返回 set1 集合里有但 set2 里没有的元素集合
  print('set2 difference set1 :${difference2l}');//返回 set2 集合里面有但 set1 里没有的元素集合
  var intersection = set1.intersection(set2);
  print('set1 set2 交集 :${intersection}');//返回 set1 和 set2 的交集
  var union = set1.union(set2);
  print('set2 set1并集:${union}');
  set2.retainAll(['java','Android']);//只保留(要保留的元素要在原 set 中存在)
  print('set2 只保留 java Android :${set2}');

Runes 符号字符

  //Runes用于在字符串中表示Unicode字符 //https://copychar.cc/emoji/
  String runesStr = '👄';
  print(runesStr);
  print(runesStr.length); //表示占 2 个 16 位字符
  print(runesStr.runes.length); //表示占 1 个 32 位字符

  Runes runes = new Runes('\u{1f605} \u6211');
  var str1 = String.fromCharCodes(runes); //使用String.fromCharCodes显示字符图形
  print(str1);
  String str2 = '\u{1f605} \u6211'; //如果非4个数值,需要把编码值放到大括号中
  print(str2)

Symbols 标识符

//Symbol标识符 主要是反射用,现在mirrors已经被移除了

函数

定义

  • 可在函数内定义
  void main(){
      int add(int x,int y){
        return x + y;
      }
    
      print(add(1,2));
  }
  • 定义函数时可省略类型
  void main(){
      add( x, y){ //不建议省略
          return x + y;
      }
      print(add(3,4));
  }
  • 支持缩写语法 =>
  void main(){
      int add2(int x,int y) => x + y;
      /// 等同于
      int add3(int x,int y){
          return x + y;
      }
       print(add2(3,4));
       print(add3(3,4));
  }

可选参数

  • 可选命名参数,使用 {param1,param2,...} 的形式来指定命名参数
  void main(){
      int add3({int x,int y,int z}){
          x ?? = 1;
          x ?? = 2;
          x ?? = 3;
          return x + y + z;
      }
      print(add3());
  }
  • 可选位置参数,把可选参数放在 [ ] 中,必填参数要放在可循参数前面
  void main(){
      int add(int x,[int y ,int z]){
          y ?? = 2;
          z ?? = 3;
          return x + y + z;
      }   
      print(add(1));
  }
  • 可选命名参数默认值(默认值必须是编译时常量),目前可使用等号 ‘=’ 或 ‘:’,Dart SDK 1.21 之前只能用冒号,冒号的支持以后会移除,所以建议使用等号
  void main(){
      int add5(int x,[int y =2,int z = 3]){
          return x + y +z;
      }
      //前面的必填参数没有名字
      print(add(5,y:10,z:20));
  }

  //可选位置参数默认值(默认值必须是编译时常量),只能使用等号 “=”
  void mian (){
      int add6(int x,[int y = 2,int z = 3]){
          return x + y + z;
      }
      
      print(add6(1));
  }

  //使用 list 或者 map 作为默认值,但必须是 const
  void func({List list = const [1,2,3],Map map = const {1:1,'fun' :'全栈'}}){
      //TODO ----
  }

匿名函数

  • 赋值给变量,通过变量调用
  //无参匿名函数
  var anonFunc1 = () => print('无参匿名函数');
  anonFunction();

  //有参匿名函数
  var anonFunc = (name) => 'I am ${name}';
  print(anonFunc('DevYK'));

  //通过()调用,不推荐
  (() => print('不推荐'))();
    
  • 可在其他函数中直接调用或传递给其他函数
  void main(){
      List test(List list,String func(str)){
          for(var i =0;i < list.length;i++){
              list[i] = func(list[i]);
          }
          return list;
      }
     
      var list = ['a','b','c','d','e'];
      print(test(list,(str) => str * 2)); // String * int ,Dart 和 Py 可以这样用。


    //List.forEach()就用的匿名函数
    List list1 = [11, 12, 13];
    list1.forEach((item) => print('$item'));
  }

闭包

  • 返回 Function 对象(闭包)
  void main(){
      Function makeAddFunc(int x){
          x++;
          return (int y) => x + y;
      }
      var addFunc = makeAddFunc(2);
      print(addFunc(3));
  }

函数别名

  • 可以指向任何同签名的函数
  void main(){
      MyFunc myFunc;
      myFunc = subtsract;
      myFunc(4,2);
      myFunc = divide;
      myFunc(4,2);
      //typeDef 作为参数传递给参数
      calculator(4,2,subtsract);
  }

  //函数别名
  typedef MyFunc(int a,int b);
  //根据 MyFunc 相同的函数签名定义两个函数
  subtsract(int a,int b){
      print('subtsract: ${a-b}');
  }
  divide(int a,int b){
      print('divide: ${a / b}');
  }
  //typedef 也可以作为参数传递给函数
  calculator(int a,int b,MyFunc func){
      func(a,b);
  }

操作符

后缀操作

  • 条件成员访问 和 . 类似,但是左边的操作对象不能为 null,例如 foo?.bar 如果 foo 为 null 则返回 null,否则返回 bar 成员。
  String a;
  print(a?.length);

取商操作符

被除数 ÷ 除数 = 商 ... 余数,A ~/ B = C,这个C就是商。相当于Java里的 /

  print(2 / 3);
  print(2 ~/ 3);

类型判定操作符

  • as、is、is! 在运行时判定对象类型
  void main(){
      //as 类型转换
  num iNum = 1;
  num dNum = 1.0;
  int i = iNum as int;
  double d = dNum as double;
  print([i,d]);

  // is 如果对象是指定的类型返回 true
  print(iNum is int);
  Child child;
  Child childl = new Child();
  print(child is Parent);//child is Null
  print(childl is Parent);

  // is! 如果对象是制定的类型返回 False
  print(iNum is! int);
  }
  class Parent {}
  class Child extends Parent {}

条件表达式

  • 三目运算符 condition ? expr1 : expr2
  bool isFinish = true;
  String textVal = isFinish ?'yes':'no';
  // expr1 ?? expr2,如果 expr1 是 non-null,返回其值; 否则执行 expr2 并返回其结果。
  bool isPaused;
  isPaused = isPaused ?? false;
  //或者
  isPaused ??= false;

级联操作符

  • 可以在同一个对象上 连续调用多个函数以及访问成员变量。 严格来说, 两个点的级联语法不是一个操作符。 只是一个 Dart 特殊语法。
  StringBuffer sb = new StringBuffer();
   sb
    ..write('Java')
    ..write('Android')
    ..write('\n')
    ..writeln('DevYK');

流程控制语句

if else

for , forEach , for-in

  • forEach
collection.forEach(item) => print('forEach: ${item}');
  • for-in
    for (var item in collection) {
      print('for-in: $item');
    }
while , do 、while

break,continue

whitch case

相关文章

网友评论

    本文标题:Flutter Dart 语言基础详解

    本文链接:https://www.haomeiwen.com/subject/jmywghtx.html