百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

Flutter 开发必备 Dart 基础:Dart 快速入门 | 开发者说·DTalk

toyiye 2024-07-06 00:32 14 浏览 0 评论

概述

Dart 从 2.0 开始变为强类型语言,静态类型。这点和 Java、C# 等比较相似。也就是说在编译时就已经知道变量的类型,就是静态类型语言。开发人员在开发的时候需要指定变量的类型。这有什么优点呢?就是所有类型检查都可以通过编译器来完成。可以提前预报一些琐碎的错误。同时 Dart 还是面向对象的编程语言。像 python、Java、Koltin、PHP 等等都是面向对象的语言。

Dart 的特性
JIT: 即时编译,开发期间做到更快的编译和更快的代码重载。但也有劣势就是在运行时需要将代码编译为机械码,那么直观感受就是慢,所以我们在开发期间有时候会发现卡顿,但是打 release 包之后效果会变好。

AOT: 事前编译,release 期间已经编译为二进制代码,所以加载会更快更流畅。

常用数据类

任何语言的基础都是数据类型,dart 也一样。dart 中主要有数字、字符串、布尔、集合和 var 类型

num 类型

num 是 dart 中的数字类型的父类,它有两个子类: int 和 double。当类型指定为 num 的时候可以赋值为小数也可以赋值为整数,但是一旦指定了某一个具体的类型,就只能赋值这一类型的值。

void _boolType() {    bool success = true; //定义bool值为true    bool failure = false; //定义bool值为false
    print(success || failure); //或运算 输出 true    print(success && failure); //且运算 输出 false  }


其中这些类型之间是可以相互转换的,如:

    print(num1.abs()); // 取绝对值 输出 2.0    print(num2.toDouble()); // 转为小数 输出4.0    print(num3.toString()); // 转为字符串 输出"5"    print(num4.toInt()); // 转为整数 输出 6


String 类型

String 的定义也比较简单,它可以使用单引号也可以使用双引号定义,定义一个 String 类型后面可以通过逗号隔开定义多个变量。在 dart 中拼接字符串可以是 + 号链接,还可以使用 $ 符号进行拼接,如果是变量则直接使用 $xx,如果是表达式则使用 ${xxx} 将其包裹起来。

  void _stringType() {    String str1 = 'str1', str2 = "str2"; //定义字符串str1和str2    String str3 = "字符串数据类型"; //定义字符串str3    String str4 = 'str1=$str1;str2=$str2'; //通过$符拼接字符串    String str5 = "str1=" + str1 + " str3=" + str3; //通过+号拼接字符串  }


字符串还有一些常用的 API,比如字符串截取,获取指定字符串位置,匹配字符串开头等等。


    print(str3.substring(1, 5)); //符串数据 输出 符串数据    print(str3.indexOf("数据")); // 获取位置 输出 3    print(str3.startsWith("字")); //匹配起始字符串 true    print(str3.replaceAll("字符串", "dart的String")); //替换 输出dart的String数据类型    print(str3.split("数")); //切够字符串 输出[字符串,据类型]


布尔类型

Dart 中布尔类型是强 bool 类型,只有 bool 类型的值为 true,才被认为是 true。bool 还有一些常用的运算符比如 || (或) 或者 && (且),在运算的时候,教大家一个口诀就是,且同真为真,或同假为假。


void _boolType() {    bool success = true; //定义bool值为true    bool failure = false; //定义bool值为false
    print(success || failure); //或运算 输出 true    print(success && failure); //且运算 输出 false  }


集合类型

dart 中定义集合直接使用 List list=[],如果没有指定泛型,默认类型为 dynamic 类型,集合中可以添加任何数据类型的数据,一旦指定了泛型,那么就只能添加约束的类型数据。除了初始化的时候添加元素另外还可以通过 API 的方式像集合中添加数据,add 添加单一数据,addAll 添加集合。还有另外一种方式是通过 List.generate 来生成集合,它的第一个参数表示集合的大小,第二个参数表示集合的元素。

void _listType() {    List list = [1, 2, 3, "list"]; //泛型为dynamic    //报 type 'List<dynamic>' is not a subtype of type 'List<int>' 异常    //因为指定了intList的泛型为int 但是list的泛型为dynamic,随意赋值失败  //List<int> intList = list;    List<int> intList2 = [1, 2, 3, 4, 5]; //定义int集合    list.add("hello"); //添加单一元素    list.addAll(intList2); //添加集合    print(list); //输出 [1, 2, 3, "list","hello",1, 2, 3, 4, 5]
    List<String> strList = List.generate(2, (index)=> "我是第$index个元素"); //通过generate定义一个String集合    print(strList); //输出 [我是第0个元素, 我是第1个元素]??}

有了集合那么我们就需要遍历它,dart 中常用的遍历集合方式有:


1, 2, 3, "list","hello",1, 2, 3, 4, 5


上面三种遍历方式输出结果都为:

1, 2, 3, "list","hello",1, 2, 3, 4, 5

Map 类型

Map 类型是将 key 和 value 相关联的对象,key 和 value 可以是任意类型的数据,并且 key 是唯一的,如果 key 重复那么后添加的会覆盖之前添加的数据。定义 map 类型直接看代码:


void _mapList() {    Map map = {"lisi": 20, "zhangsan": 24}; //直接通过 {key:value} 方式定义    Map map2 = {};    map2[11] = 20;    map2["zhangsan"] = "24";    //上面两个效果是一样的且都没有指定泛型。    Map<int, int> intMap = {1: 2, 3: 4}; //指定map的泛型  }


下面我们看下 Map 的遍历:

map.forEach((key, value) {      print(          "key:$key,value:$value"); //输出 key:lisi,value:20 和 key:zhangsan,value:24    });
    map.map((key, value) {      return MapEntry(value, key); //返回一个新的map对象,我们将key value值进行颠倒后返回    }).forEach((key, value) {      print("key:$key,value:$value"); //输出 key:20,value:lisi 和 key:24,value:zhangsan    });
    for(var key in map.keys){ //遍历map的key元素 同理还可以遍历map.values      print(key); //输出 lisi 和 zhangsan    }


dynamic、var、Object 的区别

dynamic: 动态数据类型,是所有 dart 对象的基础类型, 在大多数情况下,通常不直接使用它,通过它定义的变量会关闭类型检查,这意味着 dynamic x = 'hello world'; 调用 x.foo() 方法时静态类型检查不会报错,但是运行时会 crash,因为 x 并没有 foo() 方法,所以建议大家在编程时不要直接使用 dynamic。

var: 是一个关键字,意思是 "我不关心这里的类型是什么。",系统会自动推断类型 runtimeType;而且一旦指定了类型,就不可以修改。

Object: 是 dart 对象的基类,当你定义: Object obj=xxx 时这时候系统会认为 obj 是个对象,你可以调用 obj 的 toString() 和 hashCode() 方法,因为 Object 提供了这些方法,但是如果你尝试调用 obj.foo() 时,静态类型检查会进行报错。

综上不难看出 dynamic 与 Object 的最大的区别是在静态类型检查上。

面向对象

类的定义和构造

定义一个 dart 类,使用 class 关键字加上类名,构造方法和类名相同,默认所有的类都是继承 Object 的。其中可以定义一些方法和变量,如:

class Person {  String name;  int age;  //标准构造方法  Person(this.name, this.age);
  //重载父类的toString方法 也是多态的重要体现  @override  String toString() {    return "name=$name,age=$age";  }}


一个类继承另一个类使用关键字 extends,如果父类没有默认无参构造函数,那么子类需要使用 super 对父类进行初始化,子类的变量使用 this.xxx 来指定初始化,如:


class Worker extends Person {
  String workType;  String workAddress;  //通过this来初始化子类字段,将其他字段交由父类初始化  Worker(this.workType,this.workAddress,String name, int age) : super(name, age);}


上面代码中的: super(name,age) 被称作为初始化列表,除了调用父类构造器,还可以初始化实例变量,不同的初始化变量之间用逗号隔开。

class Worker extends Person {
  String workType;  String workAddress;  String companyName;  //通过this来初始化子类字段,将其他字段交由父类初始化,这里指定了companyName的初始化。  //如果要初始化变量,那么其不可以在构造方法中定义  Worker(this.workType, this.workAddress, String name, int age)      : companyName = "world",        super(name, age);}


我们还可以通过命名构造函数的方式初始化实例类。使用就是类名.xx() 即可,主要注意的是当有变量的类型是 final 的时候,命名构造方法就要求其在构造方法中指定进行初始化。

class Worker extends Person {
  ......  //命名构造函数  Worker.begin(Worker work) : super(work.name, work.age) {    print("命名构造函数");  }
  //假如有变量final String workAddress,那么就需要在构造方法中指定:  //Worker.begin(Worker work,this. workAddress) : super(work.name, work.age) {  //  print("命名构造函数");  //}
}


工厂构造函数就是都只返回同一个实例类,可以理解为 Java 中的单例模式。

class Logger {  static Logger _logger;
  factory Logger() {    if (_logger == null) {      _logger = Logger._initInstance();    }    return _logger;  }  //通过命名构造函数初始化  Logger._initInstance();}


还有一种构造方法是命名构造和工厂构造的结合体,通常在网络请求的时候将 json 映射为 object 的时候使用,它有一个好处就是不需要将类的 final 变量作为参数传递给构造方法。提供了一种灵活获取类对象的方式。定义格式: factory 类名.方法名。

class Worker extends Person {
  ......
  factory Worker.workHard(Worker work) {    return Worker.begin(work, "");  }}

dart 默认都会隐式的定义 setter 方法,对非空的变量还会增加 getter 方法。但是加了私有后,外界就无法访问变量了,需要我们手动的添加 set 和 get 方法class Worker extends Person { ...... double _salary; set salary(double value) => _salary = value; get salary => _salary; ......}

抽象类和方法

使用 abstract 修饰符来定义一个抽象类,该类不能被实例化。抽象类在定义接口的时候非常有用,实际上抽象类中也包含一些实现。如果一个类继承了抽象类要么实现它的抽象方法,要么也将自己定义成抽象类。一个抽象类中不一定要有抽象方法,但是有抽象方法的类一定是抽象类。

//抽象类abstract class Animal {  //抽象方法  void eat();}
//实现抽象类class Dog extends Animal {  //实现eat方法  @override  void eat() {    print("啃骨头");  }}

mixins

mixins 是在多个类层次结构中重用代码的一种方式。要使用 mixins,在 with 关键字后面跟一个或多个 mixin 的名字 (用逗号分开),并且 with 要用在 extends 关键字之后。

mixins 的特征: 实现 mixin ,就创建一个继承 Object 类的子类 (不能继承其他类),不声明任何构造方法,不调用 super。

class Logger {  static Logger _logger;
  factory Logger() {    if (_logger == null) {      _logger = Logger._initInstance();    }    return _logger;  }  //通过命名构造函数初始化  Logger._initInstance();}

方法定义
方法是由返回值类型+方法名+参数构成。其中返回值类型可缺省,也可为 void 或者具体的类型。正常情况下都是有方法名的,但有一种特殊就是匿名方法。参数分为参数类型和参数名,其中参数类型可缺省。参数又分为可选参数和默认参数,他们都使用 {} 来定义。

class FunClass {  //city为可选参数,town为默认参数  String fromWhere(country, {String city, String town = "小红帽村"}) {    if (city != null) {      return "我来自 $country $city $town";    } else {      return "我来自 $country $town";    }  }}

我们来调用打印下看看:

class Worker extends Person {
  ......
  factory Worker.workHard(Worker work) {    return Worker.begin(work, "");  }}

匿名方法有时候也被称为 lambda 或者 closure 闭包,可以把匿名方法赋值给一个变量,直接调用变量名即可。

var printI = (i) => print(i);

使用:

FunClass funClass = FunClass();funClass.printI(999);

泛型

泛型主要是解决类、接口、方法的复用性、以及对不特定数据类型的支持。

class Cache<T> {  static final Map<String, Object> _cached = Map();  void setItem(String key, T value) {    _cached[key] = value;  }  ///泛型方法  T getItem(String key) {    return _cached[key];  }}

这里我们定义了一个缓存类,存储的类型被定义为泛型,提高代码的复用度。
有时候我们在实现类似通用接口的泛型中,期望的类型是某些特定类型时,这时可以使用类型约束。

class Member<T extends Person> {  T _person;  ///泛型作用:约束参数类型  Member(this._person);
  String fixedName() {    return 'fixed:${_person.name}';  }}


总结
本文主要是讲解了在 Flutter 中常用到的 dart 的基础知识,当然还有其他很多的知识点没有涉及到。这里推荐几个 dart 学习网站给大家使用。

相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码