Flutter系列文章目录导读:

(一)Flutter学习之Dart变量和类型系统
(二)Flutter学习之Dart展开操作符 和 Control Flow Collections
(三)Flutter学习之Dart函数
(四)Flutter学习之Dart操作符、控制流和异常处理
(五)Flutter学习之Dart面向对象
(六)Flutter学习之Dart异步操作详解
(七)Flutter 学习之开发环境搭建
(八)Flutter 和 Native 之间的通信详解
(九)Android 项目集成 Flutter 模块
(十)Flutter FutureBuilder 优雅构建异步UI
更新中…


前言

前些日子在公司尝试着使用 Flutter 开发一些功能。要想写好 Flutter 程序,首先 Dart 语言是基础。

当然,在实际开发中,可能由于时间的关系,不用了解到 Dart 的方方面面才开始 Flutter 的开发,可以边学边用。

为了形成一个完整的体系,我想先系统的讲解下 Dart 语言,然后在开始 Flutter 相关的介绍。

Dart 相对于 Java 来说有更强的变现力,甚至我觉得比 Kotlin 还要有表现力。Dart 不仅可以用来开发客户端,还可以用来开发Web前端和后端开发。

所以呢,我觉得 Dart 还是一门值得学习的语言,下面就开始我们的 Dart 学习之旅吧

本文是 Dart 相关的第一篇,主要介绍 Dart 语言的变量的定义和类型体系

Hello World

按照惯例,学习一门语言都是从 Hello World 开始的。下面我们看下 Dart 的 Hello World 程序:

main(){var str = "Hello world!";print(str);}
  • 首先我们定义了顶级的 main 函数,这个程序的入口,如果没有返回值可以省略函数的返回类型
  • 然后我们通过 var 关键字定义了一个字符串,通过类型推导,str是一个字符串类型的变量
  • 最后通过系统的 print 函数输出 str 变量

变量的定义

上面我们提到了 Dart 是支持类型推导的,所以在定义变量的时候可以通过 var 关键字来定义

当然也可以显示的指定 变量的类型,如:

// 通过 var 关键字定义变量,省略具体的类型
var str = "Hello world!";// 显式指定变量类型
String str = "Hello World!"

在 Dart 中万物皆对象,如 null、函数、数字 都是对象

所以我们的定义的变量如果没有给初始值,那么这个变量的默认是就是 null

int lineCount;
assert(lineCount == null);

定义变量的时候,可以使用 final 关键字来修饰,如

final String name = "chiclaim";name = "johnny"; // Error

final定义的变量,在定义的时候就要初始化,并且只能赋值一次

定义变量的时候还可以使用 const 关键字来修饰:

const name = "chiclaim"name = "johnny"; // Error

const 关键字修饰变量,说明这个变量是 编译时常量,如数字、字符串字面量都是 编译时常量

constfinal 区别是 final 表示这个变量只能被赋值一次,const 表示该变量不仅只能被赋值一次,并且该变量是一个常量

const 不仅可以修饰变量,还可以修饰变量的值,表示该值不能修改:

main(){// 通过 const 关键字修饰foo变量的值var foo = const [];// 由于 foo 的值被 const 修饰,所以不能修改里面的值// 运行时错误,Unsupported operation: Cannot modify an unmodifiable listfoo[0] = 0;// 可以赋值,因为 foo 变量没有被 final 或 const 修饰foo = [1,2,3];// 由于foo变量被重新赋值,所以可以修改里面的值foo[0] = 0;print(foo);}

Dart类型系统

Dart 类型系统如下所示:

  • numbers(数字如整型,浮点型等)
  • strings(字符串)
  • booleans (布尔值)
  • lists (集合框架和数组)
  • sets (Set集合)
  • maps (Map集合)
  • runes (表达Unicode字符)
  • symbols (一般用不到)

numbers

不像 C/C++/Java 等语言,在 Dart 表示数字的类型只有两个:int 和 double

  • int :表示没有小数点的整型,最大值不大于64-bit(-2^63 ~ 2^63-1)底层依赖的系统最大值也不同,如果编译后用于JavaScript,则最大值为 -2^53 ~ 2^53-1

  • double 表示双精度的浮点型

int age = 17;double weight = 65.5;double waistline = 30; // 相当于 30.0

需要注意的是两个 int 相除 返回一个 double, 例如:

assert(5 / 2 == 2.5); // Result is a double

如果程序需要的是 int 可以使用 ~/ 操作符, 更多的操作符详见 (四)Flutter学习之Dart操作符、控制流和异常处理

字符串和数字类型之间互转:

// 字符串转化成整型
int num = int.parse("2");// 字符串转化成浮点型
double pi = double.parse("3.14");// 浮点型转成字符串
String piStr = 3.14.toString();// 浮点型转成用小数表示的字符串(可以选择保留几位小数)
String piAsStringFix = 3.14159.toStringAsFixed(2);

string 字符串

字符串的创建

一个 Dart 字符串是个 UTF-16 码元(code units)序列,可以使用单引号或双引号来创建一个字符串

// 双引号创建一个字符串字面量
var s1 = 'Single quotes work well for string literals.';
// 单引号创建一个字符串字面量
var s2 = "Double quotes work just as well.";
//  单引号创建字符串字面量(需要转义符)
var s3 = 'It\'s easy to escape the string delimiter.';
var s4 = "It's even easier to use the other delimiter.";

创建原生(raw)字符串,在字符串前面加上前缀 r

// 一般 \n 是换行符,如果我们想把 \n 当做字符串输出时候,也可以使用创建原生字符串的方式
var raw = r'In a raw string, not even \n gets special treatment.';

我们还可以将表达式(${expression})嵌入字符串中:

const name = "chiclaim";
// 将表达式${expression}嵌入字符串中
var info = "My name is ${name}";
// 如果表达式是一个标识符,可以省略花括号
var info2 = "My name is $name";

字符串的拼接:

// 1. 通过 + 号来拼接字符串
var s2 = 'The + operator ' + 'works, as well.';// 2. 毗邻的字符串字面量
var s1 = 'String ''concatenation'" works even over line breaks.";// 3. 通过多行字符串(使用三引号)
var s1 = '''
You can create
multi-line strings like this one.
''';var s2 = """This is also a
multi-line string.""";

字符串常用的函数

1. 字符串查询相关
  • contains(str) 字符串中是否包含某个字符串
  • startsWith(str) 字符串是否以某个字符串开头
  • endsWith(str) 字符串是否以某个字符串结尾
  • indexOf(str) 字符串在目标字符串中的位置
// Check whether a string contains another string.
assert('Never odd or even'.contains('odd'));// Does a string start with another string?
assert('Never odd or even'.startsWith('Never'));// Does a string end with another string?
assert('Never odd or even'.endsWith('even'));// Find the location of a string inside a string.
assert('Never odd or even'.indexOf('odd') == 6);
2. 字符串提取
  • substring(startIndex,endIndex) 字符串截取
  • split(Pattern) 字符串分割
  • length 字符串长度
  • [index] 通过索引获取字符串中UTF-16编码单元
  • codeUnits 返回字符串的UTF-16编码单元的不可修改的List
// 字符串截取
assert('Never odd or even'.substring(6, 9) == 'odd');// 使用正则表达式分割字符串,返回字符串集合
var parts = 'structured web apps'.split(' ');// 通过索引获取字符串的UTF-16编码单元
assert('Never odd or even'[0] == 'N');// 循环打印字符串中的字符串
for (var char in 'hello'.split('')) {print(char);
}// 获取字符串中的所有UTF-16码元
var codeUnitList ='Never odd or even'.codeUnits.toList();// N 的 ASCII 编码的十进制就是 78
assert(codeUnitList[0] == 78);
3. 大小写转换
  • toUpperCase 将字符串全部转成大写
  • toLowerCase 将字符串全部转成小写
// 转成大写
assert('structured web apps'.toUpperCase() == 'STRUCTURED WEB APPS');// 转成小写
assert('STRUCTURED WEB APPS'.toLowerCase() ==  'structured web apps');
4. 字符串的头尾空格的移除和空字符串
  • trim 去除头和尾的空格
  • isEmpty 字符串是否为空
  • isNotEmpty 字符串是否不为空
// 去除头尾的空格
print('  hello  '.trim() == 'hello');// 字符串是否为空
print(''.isEmpty);// 空格不是空字符串
print('  '.isNotEmpty);// 空格trim后,就变成空字符串
print('  '.trim().isNotEmpty);
5. 字符串部分替换
  • replaceAll

字符串是不可变的,替换函数不是修改原字符串,而是会产生一个新的字符串

var greetingTemplate = 'Hello, NAME!';
var greeting =  greetingTemplate.replaceAll(RegExp('NAME'), 'Bob');// greetingTemplate didn't change.
assert(greeting != greetingTemplate);
6. 字符串构建

通过编程的方式生成一个字符串,可以使用 StringBuffer 来实现,直到调用 StringBuffer.toString() 函数才会创建字符串

var sb = StringBuffer();// 通过 .. 实现链式调用
sb..write('Use a StringBuffer for ')// 写入一个字符串列表,以空格分割..writeAll(['efficient', 'string', 'creation'], ' ')..write('.');// 创建字符串
var fullString = sb.toString();assert(fullString =='Use a StringBuffer for efficient string creation.');

Boolean

在 Dart 中通过 bool 关键字来描述布尔,布尔有两个值:true和false。 true 和 false 都是编译器常量

bool isSuccess = true;
bool isFailed = false;

List

List不仅用来表示List集合(有序的数据集合),也用来表示数组

下面来看下如何创建一个List 字面量

var list = [1, 2, 3]; // 类型推导出list是 List<int>

介绍 const 关键字的时候,也用 const 修饰 List 的值 如:

var constantList = const [1, 2, 3];
// constantList[1] = 1; // Error.

Dart2.3 提供了展开操作符(… 和 …?) 让开发者更加方便的将多个值插入到集合中

var list = [1, 2, 3];
// 展开操作符(...) spread operator
var list2 = [0, ...list];var list;
// 展开操作符(...?) null-aware spread operator
var list2 = [0, ...?list];

Dart2.3 除了提供了展开操作符,还有 collection ifcollection for

// collection if
var nav = ['Home','Furniture','Plants',if (promoActive) 'Outlet'
];// collection for
var listOfInts = [1, 2, 3];
var listOfStrings = ['#0',for (var i in listOfInts) '#$i'
];
assert(listOfStrings[1] == '#1');

collection if/for 在开发Flutter的时候很有用,可以简化很多代码

Set

Set 表示一个无序的集合,下面看下如何创建一个 Set 字面量

// halogens is Set<String>
var halogens = {'fluorine', 'chlorine', 'bromine', 'iodine', 'astatine'};

创建一个空 Set :

// 通过var和泛型推导出Set类型
var names = <String>{};// 显式指定是Set类型
Set<String> names = {}; 需要注意的是下面是创建了一个Map
var names = {}; 

类似地,展开操作符collection if/for 也可以用到 Set 中

Map

Map 是一个 键值对 集合,下面来看下如何创建 Map 字面量:

// gifts is Map<String, String>
var gifts = {// Key:    Value'first': 'partridge','second': 'turtledoves','fifth': 'golden rings'
};// nobleGases is Map<int, String>
var nobleGases = {2: 'helium',10: 'neon',18: 'argon',
};

需要注意的时候,Key只能出现一次,否则会被后面的替换掉

通过中括号 [] 来添加、修改、获取Map中的元素:

var gifts = Map();
//  添加元素
gifts['first'] = 'partridge';var gifts = {'first': 'partridge'};
// 获取通过Key获取Map中的元素
assert(gifts['first'] == 'partridge');var gifts = {'first': 'partridge'};
// 修改Map中的元素
gifts['fourth'] = 'calling birds';

类似地,展开操作符collection if/for 也可以用到 Set 中

关于 Dart 的 展开操作符 以及 collection if/for 更多内容可以查看:

(二)Flutter学习之Dart展开操作符 和 Control Flow Collections

Rune

在 Dart 中,Rune类型是一个字符串的UTF-32的码点(code points),我们在介绍 String 类型的时候,提到了 code units

那么在介绍 Rune 之前,我们先来看下 code points 和 code units 是什么?

Unicode 编码为世界上所有的字母、数字、符号定义了对应的数字来表示

  • 码点:Unicode是属于编码字符集的范围。它所做的事情就是将我们需要表示的字符表中的每个字符映射成一个数字,这个数字被称为相应字符的码点(code points)
  • 码元:就是码点多少个字节能存储,比如 UTF-8 码元就是 8 bit 也就是 1 byte,UTF-16 码元就是 2 byte

因为 Dart 字符串是 UTF-16 码元的序列,描述 32-bit Unitcode 的字符串需要特殊的语法

通常地, Unicode使用 \uXXXX 描述码点 ,这里的 XXXX 是一个4位十六进制的值,例如描述心形的符号使用 \u2665 表示

如果多于或者少于 4 个十六进制,则需要加上花括号,例如笑的表情使用 \u{1f600}

String 类有几个属性可以提取字符串的 rune 信息 (例如属性 runes),codeUnitAtcodeUnit 属性返回 16 bit的 码元(code units)

main() {var clapping = '\u{1f44f}';print(clapping);print(clapping.codeUnits);print(clapping.runes.toList());Runes input = new Runes('\u2665  \u{1f605}  \u{1f60e}  \u{1f47b}  \u{1f596}  \u{1f44d}');print(new String.fromCharCodes(input));
}

Object 和 dynamic

在 Dart 所有的类都是继承自 Object,和Java类似。dynamic 和 Object 允许所有的值赋值给它:

dynamic name;
Object email;main() {name = "chiclaim";email = "chiclaim@gmail.com";
}

但是他们是两个完全不同的概念。你甚至可以把 dynamic 不要当做一个类型看待,dynamic 顾名思义就是动态的意思,它只是告诉编译器不要做类型检查

dynamic name;
Object email;main() {// 将 String 赋值给 namename = "chiclaim";// 打印 name 的长度print(name.length);// 将 int 赋值给namename = 1;// 编译器并不会报错(编译时不做类型检查),运行时才会报错// NoSuchMethodError: Class 'int' has no instance getter 'length'.print(name.length);email = "chiclaim@gmail.com";// 编译器报错,因为 Object 没有 length 属性print(email.length);
}

通过上面的代码示例,相信你对 dynamic 和 Object 的区别有了比较清楚的理解

Dart 在官网的最佳实践中建议开发者,如果你想表达意思是任何对象都可以,使用 Object 代替 dynamic

如果你允许类型推导失败,一般推到失败,编译器会默认给dynamic,但是建议显式地写上 dynamic ,因为代码的阅读者不知道你是忘记了写类型还是:

// 建议
dynamic mergeJson(dynamic original, dynamic changes){
}// 不建议
mergeJson(original, changes){
}

Dart几个重要的概念

  • 万物接对象:null、函数、数字
  • Dart有类型推导功能,定义变量是可以不指定变量类型,如果不想指定类型,可以使用 dynamic 类型
  • Dart支持泛型,如 List<Int>、List<dynamic>
  • Dart支持 top-level 函数,也支持成员函数和静态函数,同时也支持函数的嵌套
  • Dart没有 public、private、protected 关键字来控制访问权限,Dart 通过下划线来控制访问权限,如果以下划线开头,则表示只能在 library 内可见

Reference

关于 Dart 变量和类型系统 就讲到这里, 更多的关于 Android 学习资料可以查看我的GitHub: https://github.com/chiclaim/AndroidAll

https://dart.dev/guides/language/language-tour
https://github.com/acmerfight/insight_python/blob/master/Unicode_and_Character_Sets.md


如果你觉得本文帮助到你,给我个关注和赞呗!

另外,我为 Android 程序员编写了一份:超详细的 Android 程序员所需要的技术栈思维导图

如果有需要可以移步我的 GitHub -> AndroidAll,里面包含了最全的目录和对应知识点链接,帮你扫除 Android 知识点盲区。 由于篇幅原因只展示了 Android 思维导图:

(一)Flutter 学习之 Dart 变量和类型系统相关推荐

  1. (四)Flutter 学习之 Dart 操作符、控制流和异常处理

    Flutter系列文章目录导读: (一)Flutter学习之Dart变量和类型系统 (二)Flutter学习之Dart展开操作符 和 Control Flow Collections (三)Flutt ...

  2. Flutter学习之Dart语法特性

    一.前言 第一天把Flutter环境搭建了,并简单实现第运行第一个Flutter项目,感觉很不错,一些基本操作和原生体验差不多.用Flutter框架写过App项目的开发者都知道,Flutter是一个使 ...

  3. Flutter学习之Dart语言注释

    文章目录 1.单行注释 2.多行注释 3.文档注释 高效Dart注释 注释 注释句子化 避免使用块注释 文档注释 使用 /// 注释成员和类型 优先为public的接口编写注释 考虑写一个库级别的文档 ...

  4. Flutter学习之Dart语言基础(内置类型)

    Dart支持以下内置类型: numbers strings booleans lists (也称为数组) sets maps runes (用于在字符串中表示Unicode字符) symbols Nu ...

  5. Flutter学习笔记-Dart语言学习(五)

    内置类型(二) Lists 数组 (Array) 是几乎所有编程语言中最常见的集合类型,在 Dart 中数组由List对象表示.通常称之为 List. Dart 中的列表字面量是由逗号分隔的一串表达式 ...

  6. iOS程序猿的flutter学习之路

    日常学习Flutter开发的积累 推荐一些平时自己学习Flutter开发当中接触到的优秀文章 -------------------------基础知识 ----------------------- ...

  7. Flutter学习笔记学习资料推荐

    对Flutter的学习已经有一段时间了,这里做一下总结记录,东西比较多,可能主要是一些学习资料的记录,还有一些杂七杂八的学习笔记. 文章目录 Flutter 初体验 Flutter 环境配置 Flut ...

  8. Flutter学习记录-开篇

    Flutter学习记录-开篇 此博客是记录学习Flutter中的内容及遇到的一些问题. 我是跟着<Flutter实战>这本书来学习Flutter的. 以下是关于此书的一些简单介绍. 作者: ...

  9. 【Flutter】Flutter 开发环境搭建 ( Android Studio 下 Flutter / Dart 插件安装 | Flutter SDK 安装 | 环境变量配置 | 开发环境检查 )

    文章目录 一.Flutter 学习资料 二.Flutter 开发环境搭建 三.Android Studio 环境安装 Flutter / Dart 插件 四.下载 Flutter SDK 五.设置 F ...

最新文章

  1. linux 报错 ip_conntrack version 2.4 (8192 buckets, 65536 max) - 304 bytes per conntrack 解决方法
  2. [云炬创业基础笔记]第六章商业模式测试1
  3. 关于Java在Linux or Android平台调用.so库
  4. 【CodeForces - 485D】Maximum Value (枚举,用数组离散化,数学,取模运算,因子,筛法)
  5. Python3并发编程-多线程threading怎么用?
  6. 【目标检测实战】目标检测实战之一--手把手教你LMDB格式数据集制作!
  7. Atitit. 包厢记时系统 的说明,教程,维护,故障排查手册v2 pb25.doc
  8. solidity之call相关函数
  9. 多进程——守护进程例子
  10. linux下配置PPTP协议×××
  11. 【色彩管理】HSI色彩模式详解
  12. 001电机的分类:不骗你,如果你没读这篇文章,可能都不知道还有这种类型的电机!
  13. POJ 3689 Equations 题解 《挑战程序设计竞赛》
  14. 质数距离 数论(线性筛选素数 合数存在素数因子)
  15. 永中java的窗口_永中Office二次开发技术手册 PDF 下载
  16. 来自腾讯的高性能服务器架构思路
  17. 谷歌Flan-T5诞生!1800种语言任务超大规模微调
  18. 安全运维体系建设思路
  19. 华为eNSP基础命令
  20. 什么是变量,和变量的类型

热门文章

  1. 【现代软件工程】结对编程 —— 四则运算UI
  2. 创意思维导图绘制技巧
  3. 中投民生:今日A股大面积飘绿;注册制独领风骚
  4. 自动计算器c语言,C语言实现计算器
  5. php教程MYSQL学习视频PHP程序员基础视频课程
  6. 可视化绘图技巧100篇分析篇(二)-生存曲线(LM曲线)(补充篇)
  7. 文华财经指标公式 拿大趋势吃大利润公式指标软件,多空买卖点趋势加密WH6破解wh7随身行
  8. 高中生计算机类特长怎么写,高考报名表特长怎么写
  9. O泡恶搞v1.0安卓
  10. 苹果7全网通经常显示无服务器,抖音教会我8个iPhone隐藏技巧,就连苹果老用户也未必全知道...