dart string 转 bool_Flutter基础-Dart基础语法

763e2ded4796dff13dbc6faf3673c52e.png
Flutter基础-Dart基础语法https://www.zhihu.com/video/1251519245034733568

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

作者: The Net NinJa

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

5278ec634ce09bb2566a6659db5e4d0e.png

变量

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

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 = <String>{};
//添加单个元素
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<int, String>();
// 检索Map是否含有某Key
myMap.containsKey(1);
//删除某个键值对
myMap.remove(1); 

int、double、string相互转换

// String -> int
var one = int.parse('1');
// String -> double
var onePointOne = double.parse('1.1');
// int -> String
String oneAsString = 1.toString();
// double -> String
String 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<int> list = const [1, 2, 3],
    Map<String, String> 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<String>参数的可选参数。

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

匿名函数

正常的函数是这样的

void setName(String name){
}

是这样的

String getName(){
}

匿名函数是这样的

(){
}

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

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

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

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

打印结果:

0: apples
1: bananas
2: 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));
}
运行结果:
5
7
这个要多品品~不懂的一定要来群里问,大家一起讨论,这个一定要懂!

控制流和语句

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时,才会去执行doSomething
while (!isDone()) {
  doSomething();
}

do-while:

只有循环体中的语句被执行后,才去测试循环条件,

只有循环条件成立,就继续执行下去,不成立就跳出循环。

//先去执行一次printLine(),再去判断atEndOfPage()是否返回false
do {
  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赋值为3
p.y = 3;
// 打印p.y
print(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接口。

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

//定义一个父类Vehicle
class 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 赋值给 a
a = 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,20
Mario,30

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

作业:把文章中的代码,在DartPad中敲一遍,DartPad有国内特供版。地址:https://dartpad.cn/


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

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

关注公众号“bsmg513”,跟我们一起打卡学习吧~


今日推荐文章:
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【写的很棒】

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值