Flutter学习 -- Dart语言一

58 阅读4分钟

一、定义变量

1.1 声明变量
  变量类型 变量名称 = 赋值

示例:

String name = 'coderwhy';int age = 18;double height = 1.88;
1.2 类型推导
   var/dynamic/const/final 变量名称 = 赋值;
    // var
    var name = 'coderwhy';
    name = 'kobe'; // 同类型
    
    // dynamic
    dynamic name = 'coderwhy';
    name = 18; // 可以不同类型 不建议使用

   // final和const都是用于定义常量的, 定义之后值都不可以修改
   final name = 'coderwhy';
   
   const age = 18;
final和const区别
  • const在赋值时, 赋值的内容必须是在编译期间就确定下来的
  • final在赋值时, 可以动态获取
    String getName() {  
        return 'coderwhy';
    }
    main(List<String> args) {  
        const name = getName(); // 错误, 因为要执行函数才能获取到值  
        final name = getName(); // 正确
    }

二、数据类型

2.1 数字类型
 int age = 18;
 double height = 1.88;

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

  // 字符串转数字
  var one = int.parse('111');
  var two = double.parse('12.22');
  print('${one} ${one.runtimeType}'); // 111 int
  print('${two} ${two.runtimeType}'); // 12.22 double
  
  // 数字转字符串
  var num1 = 123;
  var num2 = 123.456;
  var num1Str = num1.toString();
  var num2Str = num2.toString();
  var num2StrD = num2.toStringAsFixed(2); // 保留两位小数
  print('${num1Str} ${num1Str.runtimeType}'); // 123 String
  print('${num2Str} ${num2Str.runtimeType}'); // 123.456 String
  print('${num2StrD} ${num2StrD.runtimeType}'); // 123.46 String
2.2 布尔类型

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

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

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

  var message = 'Hello Dart'; 
  // 错误
  if (message) { 
      print(message) 
  }
2.3 字符串类型
  // 1.定义字符串的方式
  var s1 = 'Hello World';

  // 2.表示多行字符串的方式
  var message1 = '''
  哈哈哈
  呵呵呵
  嘿嘿嘿''';

  // 3.拼接其他变量
  var name = 'coderwhy';
  var age = 18;
  var height = 1.78;
  print('my name is ${name}, age is $age, height is $height');
2.3 集合类型
2.3.1 定义 -- List/Set/Map
  • List
  // List定义
  // 1.使用类型推导定义
  var letters = ['a', 'b', 'c', 'd'];
  print('$letters ${letters.runtimeType}'); // [a, b, c, d] List<String>

  // 2.明确指定类型
  List<int> numbers = [1, 2, 3, 4];
  print('$numbers ${numbers.runtimeType}'); // [1, 2, 3, 4] List<int>

  // 扩展操作符
  var list = [1, 2, 3];
  var list2 = [0, ...list];
  print('$list2 ${list2.runtimeType}'); // [1, 2, 3, 4] List<int>

  // 空感知扩展操作符
  var list1;
  var list4 = [0, ...?list1];
  print('$list4 ${list4.runtimeType}');// [0] List<dynamic>

注:扩展操作符...)和 空感知扩展操作符...?)提供了一种将多个元素插入集合的简洁方法

  • Set 一组特定元素的无序集合
  // 1.使用类型推导定义
  var lettersSet = {'a', 'b', 'c', 'd'};
  print('$lettersSet ${lettersSet.runtimeType}'); // {a, b, c, d} _Set<String>

  // 2.明确指定类型
  Set<int> numbersSet = {1, 2, 3, 4};
  print('$numbersSet ${numbersSet.runtimeType}'); // {1, 2, 3, 4} _Set<int>

注:SetList最大的两个不同就是:Set是无序的,并且元素是不重复的

  • Map 常说的字典类型
  // 1.使用类型推导定义
  var infoMap1 = {'name': 'why', 'age': 18};
  print('$infoMap1 ${infoMap1.runtimeType}'); 
  // {name: why, age: 18} _Map<String, Object>

  // 2.明确指定类型
  Map<String, Object> infoMap2 = {'height': 1.88, 'address': '北京市'};
  print('$infoMap2 ${infoMap2.runtimeType}'); 
  // {name: why, age: 18} _Map<String, Object>
2.3.2 常见基础操作 -- List/Set/Map
  • length
  var letters = ['a', 'b', 'c', 'd'];
  var lettersSet = {'a', 'b', 'c', 'd'};
  Map<String, Object> infoMap2 = {'height': 1.88, 'address': '北京市'};
  print(letters.length); // 4
  print(lettersSet.length); // 4
  print(infoMap2.length); // 2
  • List/Set 的添加、删除、包含
var letters = ['a', 'b', 'c', 'd'];
  var lettersSet = {'a', 'b', 'c', 'd'};
  // 增加
  letters.add('e');
  lettersSet.add('e');
  print(letters);
  print(lettersSet);

  // 删除
  letters.remove('d');
  lettersSet.remove('d');
  print(letters);
  print(lettersSet);

  // 包含
  print(letters.contains('a'));
  print(lettersSet.contains('a'));

  // list 根据index删除
  letters.removeAt(0);
  print(letters);
  • Map操作
    var infoMap1 = {'name': 'why', 'age': 18};
  // 1.根据key获取value
  print(infoMap1['name']); // why

  // 2.获取所有的entries
  print('${infoMap1.entries} ${infoMap1.entries.runtimeType}'); // (MapEntry(name: why), MapEntry(age: 18)) MappedIterable<String, MapEntry<String, Object>>

  // 3.获取所有的keys
  print('${infoMap1.keys} ${infoMap1.keys.runtimeType}'); // (name, age) _CompactIterable<String>

  // 4.获取所有的values
  print('${infoMap1.values} ${infoMap1.values.runtimeType}'); // (why, 18) _CompactIterable<Object>

  // 5.判断是否包含某个key或者value
  print('${infoMap1.containsKey('age')} ${infoMap1.containsValue(18)}'); // true true

  // 6.根据key删除元素
  infoMap1.remove('age');
  print('${infoMap1}'); // {name: why}

三、函数

3.1 基本定义

函数的定义方式:

  返回值 函数的名称(参数列表) {
      函数体
      return 返回值
 }
 int sum(num num1, num num2) {
    return num1 + num2;
 }

箭头函数

  sum(num1, num2) => num1 + num2; // 函数体内只包含一个表达式
3.2 参数

参数可以分为:必选参数、可选参数。可选参数又分为命名可选参数位置可选参数

    命名可选参数: {param1, param2, ...}
    位置可选参数: [param1, param2, ...]

命名可选参数

  // 命名可选参数
  printInfo1(String name, {int? age, double? height}) {
    print('name=$name age=$age height=$height');
  }

  // 调用printInfo1函数
  printInfo1('why'); // name=why age=null height=null
  printInfo1('why', age: 18); // name=why age=18 height=null
  printInfo1('why', age: 18, height: 1.88); // name=why age=18 height=1.88
  printInfo1('why', height: 1.88); // name=why age=null height=1.88

位置可选参数

  // 定义位置可选参数
  printInfo2(String name, [int? age, double? height]) {
    print('name=$name age=$age height=$height');
  }

  // 调用printInfo2函数
  printInfo2('why'); // name=why age=null height=null
  printInfo2('why', 18); // name=why age=18 height=null
  printInfo2('why', 18, 1.88); // name=why age=18 height=1.88

命名可选参数, 可以指定某个参数是必传的(使用@required)

// 命名可选参数的必须
  printInfo3(String name, {int? age, double? height, required String address}) {
    print('name=$name age=$age height=$height address=$address');
  }

  printInfo3('why',address: 'XX省XX市', age: 18); // name=why age=18 height=null address=XX省XX市

参数默认值

  // 参数的默认值
  printInfo4(String name, {int age = 18, double height = 1.88}) {
    print('name=$name age=$age height=$height');
  }
  printInfo4('why', age: 20); // name=why age=20 height=1.88

注:只有可选参数才可以有默认值, 必须参数不能有默认值

3.3 函数是一等公民

可以将函数赋值给一个变量,也可以将函数作为另外一个函数的参数或者返回值来使用

main(List<String> args) {
  // 1.将函数赋值给一个变量
  var bar = foo;
  print(bar); // Closure: (String) => dynamic from Function 'foo': static.

  // 2.将函数作为另一个函数的参数
  test(foo); // 传入的name:coderwhy

  // 3.将函数作为另一个函数的返回值
  var func = getFunc();
  func('kobe'); // 传入的name:kobe
}

// 1.定义一个函数
foo(String name) {
  print('传入的name:$name');
}

// 2.将函数作为另外一个函数的参数
test(Function func) {
  func('coderwhy');
}

// 3.将函数作为另一个函数的返回值
getFunc() {
  return foo;
}

3.4 匿名函数

没有名字的函数,称为匿名函数

 // 1.定义数组
  var movies = ['盗梦空间', '星际穿越', '少年派', '大话西游'];

  // 2.使用forEach遍历: 有名字的函数
  printElement(item) {
    print(item);
  }

  movies.forEach(printElement); // 盗梦空间 星际穿越 少年派 大话西游

  // 3.使用forEach遍历: 匿名函数
  movies.forEach((item) {
    print(item); // 盗梦空间 星际穿越 少年派 大话西游
  });
  // 箭头缩写法
  movies.forEach((item) => print(item)); // 盗梦空间 星际穿越 少年派 大话西游
3.5 词法作用域

优先使用自己作用域中的变量,如果没有找到,则一层层向外查找

var name = 'global';
main(List<String> args) {
  var name = 'main'; 
  void foo() {
    var name = 'foo';
    print(name);
  }

  foo();
}

3.6 词法闭包
makeAdder(num addBy) {
    return (num i) {
      return i + addBy;
    };
  }

  var adder2 = makeAdder(2);
  print(adder2(10)); // 12
  print(adder2(6)); // 8

  var adder5 = makeAdder(5);
  print(adder5(10)); // 15
  print(adder5(6)); // 11
3.7 返回值问题
main(List<String> args) {
  print(foo()); // null
}

foo() {
  print('foo function');
}

四、运算符

4.1 算数以及关系运算符

+ : 加 - : 减-表达式 : 反转 * : 乘/ : 除 ~/ : 除并取整%: 取模

== != > < >= <=

  print(2 + 3 == 5); // true
  print(2 - 3 == -1); // true
  print(2 * 3 == 6); // true
  print(5 / 2 == 2.5); // true
  print(5 ~/ 2 == 2); // true
  print(5 % 2 == 1); // true

  print('5/2 = ${5 ~/ 2} r ${5 % 2}' == '5/2 = 2 r 1');// true
4.2 ?== 赋值操作
  • 当变量为null时,使用后面的内容进行赋值。
  • 当变量有值时,使用自己原来的值
main(List<String> args) {
  var name1 = 'coderwhy';
  print(name1);
  // var name2 = 'kobe';
  var name2 = null;
  name2 ??= 'james';
  print(name2); // 当name2初始化为kobe时,结果为kobe,当初始化为null时,赋值了james
}

4.3 条件表达式

条件 ? 表达式 1 : 表达式 2
如果条件为 true,执行表达式 1并返回执行结果,否则执行表达式 2 并返回执行结果。

表达式 1 ?? 表达式 2
如果表达式 1 为非 null 则返回其值,否则执行表达式 2 并返回其值。

  var temp = null;
  var name = temp ?? 'kobe';
  print(name); // kobe
4.4 级联运算符

级联运算符 (..?..) 可以让你在同一个对象上连续调用多个对象的变量或方法

class Person {
  late String name;

  void run() {
    print("${name} is running");
  }

  void eat() {
    print("${name} is eating");
  }

  void swim() {
    print("${name} is swimming");
  }
}

main(List<String> args) {
  final p1 = Person();
  p1.name = 'why1';
  p1.run();
  p1.eat();
  p1.swim();

  final p2 = Person()
    ..name = "why2"
    ..run()
    ..eat()
    ..swim();
}

五、流程控制

  • if 和 else
  • for 循环
  • while 和 do-while 循环
  • break 和 continue
  • switch 和 case
  • assert

和其他语言类似

参考文档: Dart文档 课程学习