Flutter基础-Dart基础语法

Flutter基础-Dart基础语法

​来源: https://www.youtube.com/channel/UCW5YeuERMmlnqo4oq8vwUpg

作者: The Net NinJa

视频看完了,今天内容有点儿多,但是今天的内容是后面学习Flutter的基础。如果把开发Flutter应用比喻成盖楼的话,今天的知识就是那些砖。一定要把今天的内容掌握牢,后面学起来才会更轻松。不过我保证,在这个系列中,只有今天的内容是最多的,所以大家一定要耐住性子把今天的东西学完。后面只会学起来越来越轻松~开始吧!

 

Flutter基础-Dart基础语法_第1张图片

变量

在开始讲变量之前,要先给大家看下变量的声明,举三个例子。

var name = 'Cyy'

这行代码的意思就是,我声明了一个变量,名字是name,然后给他了一个初始值Cyy。

再看下一个

dynamic name = 'Cyy';

这行代码的意思也是,我声明了一个变量,名字是name,然后给他了一个初始值Cyy。

我们继续看下一个

String name = 'Cyy';

这行代码的意思还是声明了一个变量,名字是name,然后赋值为Cyy。

但是!他与上面两个的区别是,我在这里给他声明了变量的类型,就是我指定了这个name是字符串类型的。上面两个都没有给变量指明类型,那么问题来了!

var和dynamic的区别是什么呢?

var 初始化确定类型后不可更改类型,dynamic 可以更改类型

简单说,就是如果你一开始给var的变量初始化了一个值,Dart会去推断这个值,如果是什么类型,那这个变量以后就是什么类型了,不能再改变了。但是 dynamic还是可以更改滴。

现在再来看看这三个东西吧~

默认值

在Dart中,所有的类型都是对象,未初始化的变量的初始值为null。甚至Number类型的变量最初都为null,怎么理解呢,就像java里的包装类,Integer , Double 等等。

final

final name = 'Cyy'; final String nickname = 'XiaoFo';

简单来说,被final声明过的变量,后面你就无法再更改它的值了,所以final修饰的变量必须初始化,且只能在初始化时赋值一次.

举个例子:

void main() {  final name = 'Cyy';   final String nickname = 'XiaoFo';  name = 'Cyy513'}运行结果: Error: Can't assign to the final variable 'name'.

它不会让我再去给他赋值,因为我声明它是final的变量,只允许被进行一次赋值。

const

在基础课,我们只需要知道const和final一样也只允许被赋值一次,后面不能再更改。他主要用来创建常量值、声明创建常量值的构造函数。后面用到的时候,会给大家细讲,基础阶段先暂时知道这些就可以。

常用的变量类型

Number

Number对象包含两个子对象,分别是int和double。int在不同平台位数不同,但是最大就64位。在Dart VM上,他的值从-263 到 263 - 1。这个数字啥意思,就是说int允许的最大值和最小值。double学名是双精度浮点数,初学者的话,可以这么理解,整数是不带小数点儿的,double是带小数点儿的。

怎么声明一个int型变量和double型变量呢?这样就可以了

int a = 2;double b = 1.1;

String 

就是你声明的变量是一个字符串,举个例子应该就都明白了。

 String cyy  = "hello Cyy"

也是非常简单,但是他有很多种用法:

  var sOne = 'Hello';  var stwo = 'Cyy';  var sThree = sOne + stwo; // 输出结果:HelloCyy  var sFour = '${sOne}ABC'; //HelloABC  var sFive = '$sOne $stwo'; //Hello Cyy  var sSix = '''  You can create  multi-line strings like this one.  ''';   sSix的输出结果为:  You can create  multi-line strings like this one.  -------------------------------------  var sSeven= """This is also a  multi-line string.""";  sSeven的输出结果为:  This is also a    multi-line string

会这几个就够用了~

Boolean

布尔类型,只允许两种值,true和false.

List

任何编程语言都有集合,而Dart 的集合是List。

 //创建一个int类型的list List list = [1, 2, 3]; // 输出[1, 2 3] print(list); 有两种方式可以创建List 方法一: // 使用List的构造函数 var listOne = new List(); // 添加元素 listOne.add('Mario');  // 添加多个元素 listOne.addAll(['chun-li', 'jack']); ------------------------------------------ //也可在括号里添加数字,表示List固定长度,但是不能进行添加 删除操作  var listTwo = new List(10); 如果执行了:listTwo.add('Mario'); 输出结果:Uncaught Error: Unsupported operation: add ------------------------------------------ List listThree = ['Cyy', 'XiaoFo', 'Bob']; // 添加多个元素 listThree.addAll(listOne); // 输出:[Cyy, XiaoFo, Bob, Mario, chun-li, banans] print(listThree); // 获取List的长度 print(listThree.length); // 获取第一个元素 print(listThree.first); // 获取元素最后一个元素 print(listThree.last); // 利用索引获取元素 print(listThree[0]);--------------------------------------------List还有其他几种有趣的玩儿法第一种:您可以使用运算符(...)将列表的所有元素插入另一个列表var list = [1, 2, 3];var list2 = [0, ...list];print(list2);输出结果:[0, 1, 2, 3]第二种:/*  如果扩展运算符右边的表达式可能为空,  则可以使用可识别空值的扩展运算符(...?)避免出现异常*/var list;var list2 = [0, ...?list];print(list2);输出结果:[0]第三种:还可以使用for循环添加元素到集合中var nav = [  'Home',  'Furniture',  'Plants',  if (true) 'Outlet'];print(nav);输出结果:[Home, Furniture, Plants, Outlet]

Set

List 是有序的集合,那Set就是无序的集合。

var halogens = {'fluorine', 'chlorine', 'bromine', 'iodine', 'astatine'};//创建一个空Set集合var names = {};//添加单个元素names.add('fluorine');//添加多个元素names.addAll(halogens);

Map

map是将键和值相关联的对象。键和值都可以是任何类型的对象,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';//使用.length来获取映射中的键值对的数量var gifts = {'first': 'partridge'};print(gifts.length)// 指定键值对的参数类型var myMap = new Map();// 检索Map是否含有某KeymyMap.containsKey(1);//删除某个键值对myMap.remove(1); 

int、double、string相互转换

// String -> intvar one = int.parse('1');// String -> doublevar onePointOne = double.parse('1.1');// int -> StringString oneAsString = 1.toString();// double -> StringString piAsString = 3.14159.toStringAsFixed(2);

方法

参数

举一个函数的例子,你应该就知道什么是参数了。

// 调用函数时,可以使用paramName:value指定命名参数,例如:enableFlags(bold: true, hidden: false);// 定义函数时,使用{param1,param2,…}指定命名参数,// bold和hidden就是参数,bool是他们的类型void enableFlags({bool bold, bool hidden}) {...}// 尽管命名参数是一种可选参数,但是您可以使用@required对其进行注释// 以指示该参数是强制性的-用户必须为该参数提供一个值// 如果用户不传,就会报错!const Scrollbar({Key key, @required Widget child})//在[]中包装一组功能参数会将其标记为可选参数,就是可以传,也可以不传// 例如:String say(String from, String msg, [String device]) {  var result = '$from says $msg';  if (device != null) {    result = '$result with a $device';  }  return result;}可以这么调用:say('Bob', 'Howdy', 'smoke signal')也可以这么调用:say('Bob', 'Howdy')

默认参数

您的函数可以使用=来定义命名参数和位置参数的默认值。默认值必须是编译时常量。如果未提供默认值,则默认值为null。举个栗子:

void enableFlags({bool bold = false, bool hidden = false}) {}调用:enableFlags(bold: true); //bold是true hidden是fals可选参数使用默认值:String say(String from, String msg,    [String device = 'carrier pigeon', String mood]) {  var result = '$from says $msg';  if (device != null) {    result = '$result with a $device';  }  if (mood != null) {    result = '$result (in a $mood mood)';  }  return result;}调用:say('Bob', 'Howdy')输出结果为:Bob says Howdy with a carrier pigeon------------------------------------------------您还可以将列表或地图作为默认值传递,例如:void doStuff(    {List list = const [1, 2, 3],    Map gifts = const {      'first': 'paper',      'second': 'cotton',      'third': 'leather'    }}) {  print('list:  $list');  print('gifts: $gifts');}调用:doStuff()输出结果:list:  [1, 2, 3]gifts: {first: paper, second: cotton, third: leather}

是不是很神奇,希望大家回去后,都自己去亲自敲一遍。

main函数

每个应用程序都必须有一个顶层main()函数,它可以作为应用程序的入口点。该main()函数返回void,视频中也说了,void就是不返回任何值。并具有List参数的可选参数。

void main() {  //在这里写你的逻辑}

匿名函数

正常的函数是这样的

void setName(String name){}

是这样的

String getName(){}

匿名函数是这样的

(){}

这是啥?像不像一个人没有头?

但是他跟普通函数一样,能传各种参数,普通函数能传啥参数就,他也能传。

那他平时咋用呢?再举个例子:

void main() {  var list = ['apples', 'bananas', 'oranges'];  list.forEach((item) {    print('${list.indexOf(item)}: $item');  });}打印结果:0: apples1: bananas2: oranges这个item叫啥都行,你传个a进去,效果是一样的。

老师在视频中也说了,如果该函数仅包含一个语句,则可以使用箭头符号将其缩短。那么上面那个代码就可以改成:

void main() {  var list = ['apples', 'bananas', 'oranges'];  list.forEach(    (item) => print('${list.indexOf(item)}: $item'));}

效果是一样的。

返回值

foo(){}所有函数都返回一个值。如果未指定返回值,则语句返回null;void就是没有返回值

词法范围

Dart 是静态作用域语言,变量的作用域在写代码的时候就确定过了。基本上大括号里面定义的变量就 只能在大括号里面访问,和 Java 作用域 类似。举个例子:

var topLevel = true;main() {  var insideMain = true;  myFunction() {    var insideFunction = true;    nestedFunction() {      var insideNestedFunction = true;    }  }}nestedFunction可以访问:topLevel,insideMain,insideFunction,insideNestedFunction 4个变量他拥有最高权限。myFunction可以访问:topLevel,insideMain,insideFunction 3个变量main可以访问:topLevel,insideMain 2个变量思考一下:如果main访问了insideFunction 会提示什么?答案:会提示"找不到insideFunction";

词法闭包

概念太抽象了,但是我还是要写一下,哈哈, 我好幽默。

维基百科上对闭包的解释就很经典:在计算机科学中,闭包(Closure)是词法闭包(Lexical Closure)的简称,是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。

函数可以关闭周围范围中定义的变量。在以下示例中,makeAdder()捕获变量addBy。无论返回的函数到哪里,它都会记住addBy。Function makeAdder(num addBy) {  return (num i) => addBy + I;}void main() {  // 引用了自由变量2  var add2 = makeAdder(2);  // 引用了自由变量4  var add4 = makeAdder(4);  print(add2(3));  print(add4(3));}运行结果:57这个要多品品~不懂的一定要来群里问,大家一起讨论,这个一定要懂!

控制流和语句

if和else

Dart支持if语句和可选的else语句,条件判断语句中必须是布尔值,举个例子。

if (isRaining()) {  //如果isRaining()返回true,则走这里  you.bringRainCoat();} else if (isSnowing()) {  //如果isRaining()返回false,isSnowing()返回true,则走这里  you.wearJacket();} else {  //如果isRaining()返回false,isSnowing()返回false,则走这里  car.putTopDown();}

for循环

var message = StringBuffer('Dart is fun');for (var i = 0; i < 5; i++) {  message.write('!');}pritn(message);输出结果:Dart is fun!!!!List和Set之类的可迭代类也支持for-in形式的迭代var collection = [0, 1, 2];for (var x in collection) {  print(x); //输出结果 0 1 2}

while 和do-while

while:只有测试条件成立,才会去执行循环体中的语句,否则跳出循环。// 只有isDone()返回false时,才会去执行doSomethingwhile (!isDone()) {  doSomething();}do-while:只有循环体中的语句被执行后,才去测试循环条件,只有循环条件成立,就继续执行下去,不成立就跳出循环。//先去执行一次printLine(),再去判断atEndOfPage()是否返回falsedo {  printLine();} while (!atEndOfPage());

break和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) {    // 如果candidate.yearsExperience<5    // 不执行candidate.interview();继续开始下一次循环    continue;  }  candidate.interview();}

switch和case

看个例子就明白了。

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();}相当于:if(command=='OPEN'){}else if(command=='CLOSED'){}...后面省略但是要强调几点:1. case后面如果省略了break,他就跳不出这个循环,会走到下一个case下面.2. case子句可以声明局部变量,这些局部变量仅在该子句的范围内可见3. Dart的case里面,逻辑可以是空,例如:var command = 'CLOSED';switch (command) {  case 'CLOSED': // Empty case falls through.  case 'NOW_CLOSED':    // Runs for both CLOSED and NOW_CLOSED.    executeNowClosed();    break;}

assert

在开发过程中,使用断言语句— assert(); 如果布尔条件为false,则中断执行;

类的使用

对象具有由函数和数据(分别为方法和实例变量)组成。调用方法时,您可以在对象上调用它,该方法可以访问该对象的功能和数据。

var p = Point(2, 2);//Point是一个类// 给Point类中的y赋值为3p.y = 3;// 打印p.yprint(p.y);// 3采用 ?.代替 .为了避免p为null时发生异常p?.y = 4;

构造函数的使用

您可以使用构造函数创建对象。构造函数名称可以是ClassName或ClassName.identifier。

class Point {  double x, y;  //这个就是Point这个对象的构造函数  Point(double x, double y) {    this.x = x;    this.y = y;  }}this关键字指向了当前类的实例, 上面的代码可以简化为 class Point {    num x;    num y;    // 语法棒棒糖    Point(this.x, this.y); }-----------------命名构造函数--------------------------------命名构造函数:是在初始化时可直接使用类调用class User {    String name;    int    age;    //声明一个命名构造函数    User.getInfo(String name, int age){        this.name = name;        this.age  = age;        print("命名构造函数");    }}//调用命名构造函数User u = User.getInfo();-----------------使用构造函数创建对象--------------------------例如,以下代码使用Point()和Point.fromJson()构造函数创建Point对象var p1 = Point(2, 2);var p2 = Point.fromJson({'x': 1, 'y': 2});也在构造函数名称之前使用可选的new关键字创建对象var p1 = new Point(2, 2);var p2 = new Point.fromJson({'x': 1, 'y': 2});

创建构造函数还有很多种方法,这里就不一一列举了,这里只列举了两种,总共大概有八九种,大家可以去网上看下,很多这样的文章,写的都很好。我们继续看下面的。

获取对象的类型

要在运行时获取对象的类型,可以使用Object的runtimeType属性,会返回Type对象。

print('The type of a is ${a.runtimeType}');

方法

方法是提供对象行为的函数,可以通过他访问对象的变量。

class Rectangle {   num left;   num top;   num width;   num height;      Rectangle(this.left, this.top, this.width, this.height);   // 定义两个计算属性: right and bottom.   num get right => left + width;   set right(num value) => left = value - width;   num get bottom => top + height;   set bottom(num value) => top = value - height;}main() {   var rect = new Rectangle(3, 4, 20, 15);   print(rect.left);//调用了隐含的getLeft 所以是3   rect.right = 12;//执行了上面right方法   print(rect.left);//这里left = 12-20 这块儿是个匿名函数}运行结果:3 -8这个例子多看一会儿,思考一下。

抽象方法

Instance , getter 和 setter 方法可以是抽象的,也就是定义一个接口,但是把实现交给其他的类。要创建一个抽象方法,使用分号(;)代替方法体。

 abstract class Doer {    // 定义实例变量和方法    void doSomething(); // 定义一个抽象方法。 } class EffectiveDoer extends Doer {     void doSomething() {        // 提供一个实现     } } !*****抽象类是不能被实例化的****!这句话很重要,需要被注意到,还需要细品 下面的类不是抽象类,因此它可以被实例化,即使定义了一个抽象方法  class SpecializedContainer extends AbstractContainer {    // 定义更多构造函数,域,方法    void updateChildren() {      // 实现 updateChildren()    }   // 抽象方法造成一个警告,但是不会阻止实例化。   void doSomething(); }

隐式接口

每个类都隐式地定义一个接口,该接口包含类的所有实例成员及其实现的任何接口。如果您想创建一个类A,它支持类B的API而不继承B的实现,那么类A应该实现B接口。

简单的说,当我们定义了一个类的时候,同时就会产生一个和此类同名的接口,而且此接口包含了我们定义的类中所有的方法,以及它的成员变量。

//定义一个父类Vehicleclass Person{  num age  = 0  ;  Person(){    print("super Constructor") ;  }  Person.get(){    print("super Run") ;  }  Person.create(){    print("super create") ;  }  void run(){    print("person run") ;  }  void printAge(){    print("age = > $age") ;  }}怎么用?class Cyy implements Person{  @override  void run() {    //重写了run方法    print("Cyy running");  }  @override  void printAge() {    print("Cyy age = $age") ;  }  //覆盖(实现)成员变量  @override  num age;}

继承

使用 extends 创建一个子类,同时 supper 将指向父类

 class Television {    void turnOn() {        _illuminateDisplay();        _activateIrSensor();    } } class SmartTelevision extends Television {    void turnOn() {       super.turnOn();       _bootNetworkInterface();       _initializeMemory();       _upgradeApps();    } } 当实例化SmartTelevision这个类后,调用turnOn()方法时会执行: _illuminateDisplay(),_activateIrSensor(), _bootNetworkInterface(),_initializeMemory(), _upgradeApps() 5个方法

枚举类型

枚举类型,通常被称为 enumerations 或 enums ,是一种用来代表一个固定数量的常量的特殊类。

声明一个枚举类型需要使用关键字 enum 

 enum Color {    Mario,    chun-li,    Rose } 要得到枚举列表的所有值,可使用枚举的 values 常量 例如:Color.values

Mixins

因为我们课程是基础课程,所以Mixins这里就暂时先不讲了,如果后面有需要,我们会单独写一片文章来讲解。但是我会把我觉得写的比较好的文章,放到今日推荐里,感兴趣的同学可以去看看。

 

常用的操作符

算数运算符

算数运算符,这里就不一一列出来了,大家看下方推荐文章,官方文档里有写,如果有不懂的,可以下方留言或者加群,问我们,肯定知无不言。

等号和关系运算符

要测试两个对象x和y是否表示同一事物,请使用==运算符。(在极少数情况下,您需要知道两个对象是否是完全相同的对象,请改用same()函数)

as is is!

主要是在运行过程中,用来检查类型的。

当且仅当您确定对象属于该类型时,才使用as运算符将对象转换为特定类型(emp as Person).firstName = 'Bob';也就是说,只有你确定emp是Person类型时,才能这么用。不然会报错:TypeError: "emp": type 'JSString' is not a subtype of type 'Person'----------------------------------------------------------------------------如果您不确定该对象的类型为T,使用该对象之前使用is检查类型。if (emp is Person) {  // Type check  emp.firstName = 'Bob';}

赋值运算符

// 把value 赋值给 aa = value;// 如果b为null,则为b赋值;否则,b保持不变b ??= value;

条件表达式

condition ? expr1 : expr2

如果条件为true,则返回expr1否则返回expr2。

expr1 ?? expr2

如果expr1不为null,则返回expr1否则返回expr2。

级联符号

看一个例子就明白了,暂时知道怎么用就行.

class Person {  var name;  var age;  Person(this.name, this.age);  getUserInfo() {    print("${this.name},${this.age}");  }}void main() {  var p = new Person('Cyy', 20);  p.getInfo();  //..为级联操作,可以同时赋值执行方法  p    ..name = "Mario"    ..age = 30    ..getInfo();}运行结果:Cyy,20Mario,30

好啦,今天的内容实在太多了,但我认为只要好好读,一定能学懂的。如果后面的课程遇到了一些问题,那就说明今天的内容,你没有完全掌握。本篇内容需要反复的阅读,最好每个代码都尝试着跑一遍。因为这个课程是入门课,所以一些,泛型,异步的东西,这里没有讲,感兴趣的同学可以自己去看下,后面的老师也会讲到。下篇我们就要开始Flutter征程啦~期待吧!

本文内容有点儿多,建议大家使用浏览器查看。

作业:把文章中的代码,在DartPad中敲一遍,DartPad有国内特供版。

地址:https://dartpad.cn/

学习完成别忘了打卡哦~,大家一起学习交流才更有趣。在下方评论留言 “打卡第*天”,大家互相监督,一起进步吧!

亦可加微信:wtr513 备注: "Flutter 技术交流", 进群和大家一起学习。

今日推荐文章:

Dart官网文档:

https://dart.dev/guides/language/language-tour#methods  【官方文档】

Flutter学习指南-熟悉Dart语言:

https://juejin.im/post/5bcc8527f265da0aff17729a 【玉刚说】

我是刚哥老铁粉了~~

Dart之Mixin详解:

https://blog.csdn.net/lmh_19941113/article/details/99762712【写的很棒】

 

你可能感兴趣的:(Flutter基础-Dart基础语法)