目录
- 前言
- 1.安装与使用
- 1.1 安装
- 1.2 在 vscode 中使用
- 2.类型声明
- 2.1 变量声明
- 2.1.1 var
- 2.1.2 const 和 final
- 2.1.3 dynamic 和 Object
- 2.1.4 默认值
- 2.2 数据类型
- 2.2.1 Number
- 2.2.2 String
- 2.2.4 List
- 2.2.5 Set
- 2.2.6 Map
- 2.2.7 Runes(字符)
- 2.2.8 Symbols(符号)
- 2.2.9 枚举类型
前言
最近在学习做 flutter 移动端开发。相比 React-Native 开发而言, 使用 Flutter 开发的话要使用 Dart 这门语言,导致学习负担更重一点。所以针对 Dart 语言的语法和使用做一下汇总。
以下内容参考自 Dart 官方文档
1.安装与使用
dart是由google公司开发的一门面向对象的编程语言。主要应用在移动端,配合 flutter 使用。dart2为现阶段使用的稳定版本
1.1 安装
因为学习 dart 大多数是为了写 flutter,所以推荐直接下载 flutter,下载的 flutter 中会带有 dart 的 SDK。
flutter 推荐去官网进行下载。下载完成后解压,dart 的 SDK 就在解压目录\\bin\\cache\\dart-sdk下。
1.2 在 vscode 中使用
为了方便使用,我们可以将 dart 的 SDK 设置在环境变量中,将解压目录\\bin\\cache\\dart-sdk\\bin的完整路径设置好,在cmd 中输入 dart ,有响应就代表设置成功了。
然后就是如何在 vscode 中使用dart。为了使用 dart,我需要下载两个插件Dart和Code Runner,下载完成后创建一个文件main.dart,输入如下代码:
// dart中的代码需要放入main方法中执行
main(){
print(\’Hello World\’);
}
然后右键Run Code,如果控制台成功打印出Hello World证明我们已经能够在 vscode 中使用 dart 了。
2.类型声明
2.1 变量声明
在 dart 中有很多声明变量的关键字,可以使用能接受任何类型值的变量申明(类似 JavaScript),也可以使用只能接受固定类型值的变量声明(类似 JAVA)。
2.1.1 var
类似于JavaScript中的var,它可以接收任何类型的变量,但最大的不同是 dart 中var变量一旦在声明时被赋值(除了被赋值为 null,因为初始化的时候所有的值都为 null),类型便会确定,则不能再改变其类型,如:
var t = \”hi world\”;
// 下面代码在dart中会报错,因为变量t的类型已经确定为String
// 类型一旦确定后则不能再更改其类型
t = 1000;
💡 对于前端人员来说,其实看作是 TypeScript 的自动推断类型的功能就好。
但是如果一开始没有直接赋值,而是只定义,那么变量的类型默认会是dynamic类型,也就说和 JavaScript 中的声明的变量一样的用法了。
var t;
t = \”hi world\”;
// 下面代码在dart中不会报错
t = 1000;
2.1.2 const 和 final
如果从未打算更改一个变量,那么使用 final 或 const,不是var,也不是一个单独的类型声明(类型声明也是可以更改值的,当使用类型声明定义变量时,可以直接在前面加上const或final关键字使其变成常量,但是我们一般建议省略类型声明)。
使用const和final声明的变量都只能被设置一次,两者区别在于:
const常量是一个编译时常量(就是说必须要是一个在程序编译时就完全固定的常量),final常量不仅有const的编译时常量的特性,最重要的是它是运行时常量,final是惰性初始化的,即在第一次使用时才会初始化。
// 可以省略String这个类型声明
final str = \”hi world\”;
final String sstr = \”hi world\”;
const str1 = \”hi world\”;
const String sstr1 = \”hi world\”;
// 运行时常量在运行时才会被赋值
// 获取当前时间,因为是动态获取的,所以不能通过const声明
final t = new DateTime.now(); // OK
const t1 = new DateTime.now(); // Error
注意:
虽然 final 是运行时常量,第一次被赋值也必须是在定义的时候赋值。
final a; // Error
a = 1;
实例变量可以是 final,但不能是 const。(实例变量定义在对象一级,它可以被类中的任何方法或者其他类中的方法访问,但是不能被静态方法访问)
class A {}
main() {
final a = new A(); // OK
const b = new A(); // Error
}
const 关键字不只是声明常量变量。还可以使用它来创建常量值,以及声明创建常量值的构造函数。任何变量都可以赋一个常量值。
var foo = const [];
final bar = const [];
// 可以从const声明的初始化表达式中省略const
const baz = []; // Equivalent to `const []` => const bar = const [];
// 不能改变const变量的值
baz = [42]; // Error: Constant variables can\’t be assigned a value.
// 可以更改一个非final的非const变量的值,即使它曾经有一个const值
foo = [1, 2, 3]; // Was const []
有些类提供常量构造函数。要使用常量构造函数创建编译时常量,请将 const 关键字放在构造函数名之前:
class Person{
const Person();
}
var p = const Person();
2.1.3 dynamic 和 Object
- Object 是 dart 所有对象的根基类,也就是说所有类型都是Object的子类(包括Function和Null),所以任何类型的数据都可以赋值给Object声明的对象。
- dynamic是与int这样一样的类型关键词,改类型声明的变量也可以赋值任意对象。
💡 dynamic与Object相同之处在于,它们声明的变量可以在后期改变赋值类型(类似使用 JavaScript 或 TypeScript 中的any类型)。
dynamic t;
Object x;
t = \”hi world\”;
x = \’Hello Object\’;
// 下面代码没有问题
t = 1000;
x = 1000;
dynamic与Object不同的是,dynamic声明的对象编译器会提供所有可能的组合(也就是相当于就是完完全全的 JavaScript变量),而Object声明的对象只能使用 Object 类的属性与方法,否则编译器会报错。
dynamic a;
Object b;
main() {
a = \”\”;
b = \”\”;
printLengths();
}
printLengths() {
// no warning
print(a.length);
// warning:
// The getter \’length\’ is not defined for the class \’Object\’
print(b.length);
}
2.1.4 默认值
未初始化的变量的初始值为 null。甚至具有数字类型的变量最初也是 null,因为在 dart 中所有的东西都是对象。
int lineCount;
assert(lineCount == null);
注意: 在生产环境中,assert()调用被忽略。在开发环境中当assert(condition)的 condition 条件不为真时抛出一个异常。
2.2 数据类型
我们要清楚的是,dart 中的所有类型的值全都是对象,所以在其他语言中常用的基本类型声明在 dart 中实质也是类的类型声明。
2.2.1 Number
Number 总共能使用三种类型:
- num
- int
- double
Dart的数字有两种形式:
int:根据平台的不同,整数值不大于64位。在 Dart VM 上,值可以从-263到263 – 1。编译成 JavaScript 的 Dart 使用 JavaScript 代码,允许值从-253到253 – 1。
整数是没有小数点的数。这里有一些定义整数字面量的例子:
int x = 1;
int hex = 0xDEADBEEF;
int 类型指定传统的(<<, >>)和(&),或(|)位操作符。例如:
assert((3 << 1) == 6); // 0011 << 1 == 0110
assert((3 >> 1) == 1); // 0011 >> 1 == 0001
assert((3 | 4) == 7); // 0011 | 0100 == 0111
double:64位(双精度)浮点数,由IEEE 754标准指定。
如果一个数字包含一个小数,它就是一个双精度数。这里有一些定义双精字面量的例子:
double y = 1.1;
double exponents = 1.42e5;
注: int 和 double 都是 num 的子类型。num 类型包括基本的操作符,如+、-、/和*,还可以在其中找到abs()、ceil()和floor()等方法。(位运算符,如>>,在int类中定义)如果 num 及其子类型没有要查找的内容,那么dart:math library可能会有。
以下是如何将字符串转换成数字的方法,反之亦然:
// String -> int
var one = int.parse(\’1\’);
assert(one == 1);
// String -> double
var onePointOne = double.parse(\’1.1\’);
assert(onePointOne == 1.1);
// int -> String
String oneAsString = 1.toString();
assert(oneAsString == \’1\’);
// double -> String
String piAsString = 3.14159.toStringAsFixed(2);
assert(piAsString == \’3.14\’);
2.2.2 String
dart 字符串是 UTF-16 编码单元的序列。可以使用单引号或双引号创建一个字符串:
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.\”;
可以使用${expression}将表达式的值放入字符串中。如果表达式是一个标识符,可以跳过{}。为了获得与对象对应的字符串,dart 会自动调用对象的toString()方法。
var s = \’string interpolation\’;
assert(\’Dart has $s, which is very handy.\’ ==
\’Dart has string interpolation, \’ +
\’which is very handy.\’);
assert(\’That deserves all caps. \’ +
\’${s.toUpperCase()} is very handy!\’ ==
\’That deserves all caps. \’ +
\’STRING INTERPOLATION is very handy!\’);
注意: ==检验两个对象是否相等。如果两个字符串包含相同序列的代码单元,那么它们是等价的,这点与 JavaScript 类似。
可以使用相邻的字符串字面量(也可以看做是用空格) 或 + 运算符连接字符串:
var s1 = \’String \’ \’concatenation\’ \” works even over line breaks.\”;
assert(s1 == \’String concatenation works even over \’ \’line breaks.\’);
var s2 = \’The + operator \’ + \’works, as well.\’;
assert(s2 == \’The + operator works, as well.\’);
对于创建多行字符串的方法:
- 使用\\n用做换行。
- 使用带有单引号或双引号的三重引号。
var s = \’a \\n multi-line string\’
var s1 = \’\’\’
You can create
multi-line strings like this one.
\’\’\’;
var s2 = \”\”\”This is also a
multi-line string.\”\”\”;
如果不想要转义字符你可以用r前缀创建一个原始字符串:
var s = r\’In a raw string, not even \\n gets special treatment.\’;
// In a raw string, not even \\n gets special treatment.
要注意一点,字符串字面量是编译时常量,只要任何内插表达式都是编译时常量,计算结果为 null 或数值、字符串或布尔值。
// These work in a const string.
const aConstNum = 0;
const aConstBool = true;
const aConstString = \’a constant string\’;
// These do NOT work in a const string.
var aNum = 0;
var aBool = true;
var aString = \’a string\’;
const aConstList = [1, 2, 3];
const validConstString = \’$aConstNum $aConstBool $aConstString\’;
// const invalidConstString = \’$aNum $aBool $aString $aConstList\’; // Error
/*
前三个错误因为使用var进行申明的,var声明的变量之后可以改变值,不符合常量定义,而后一个是因为不符合常量所需类型,也就是不符合null或数值、字符串或布尔值。即使使用toString()方法也会报错,这不符合编译时常量的定义,除非用final
*/
2.2.3 Boolean
为了表示布尔值,dart 有一个名为 bool 的类型。只有两个对象具有 bool 类型:布尔字面量 true 和 false,它们都是编译时常量。
dart 的类型安全性意味着不能使用if(非booleanvalue)或assert(非booleanvalue)之类的代码。相反,显式地检查值,如:
// Check for an empty string.
var fullName = \’\’;
assert(fullName.isEmpty);
// Check for zero.
var hitPoints = 0;
assert(hitPoints <= 0);
// Check for null.
var unicorn;
assert(unicorn == null);
// Check for NaN.
var iMeantToDoThis = 0 / 0;
assert(iMeantToDoThis.isNaN);
2.2.4 List
只要 List、Set、Map 等的基本用法见 dart 常用库的使用
Lst API 文档
也许几乎所有编程语言中最常见的集合就是数组或有序对象组。在 dart 中,数组是列表对象,所以大多数人把它们叫做列表。
dart 列表字面量看起来像 JavaScript 数组字面量。这是一个简单的 dart 列表:
var list = [1, 2, 3];
注意: 上面的代码分析器推断该列表具有List<int>类型。如果试图向此列表添加非整型对象,则分析器或运行时将引发错误。
可以获取列表的长度,并引用列表元素,就像在JavaScript中那样:
var list = [1, 2, 3];
assert(list.length == 3);
assert(list[1] == 2);
list[1] = 1;
assert(list[1] == 1);
要创建一个编译时常量列表(不能再之后改变值),需要在列表字面量之前添加 const(或者直接使用 const 申明变量):
var constantList = const [1, 2, 3];
// OR
const constantList = [1, 2, 3];
// constantList[1] = 1; // Uncommenting this causes an error.
// 这里不会在编译时报错,但是运行时会抛出异常
列表类型有许多便于操作列表的方法,在这里不说,在之后会进行详细说明。
2.2.5 Set
Set API 文档
dart 中的集合是一组无序的独特物品集合。因为集合是无序的,所以不能通过索引(位置)获得集合的项。
var ingredients = Set();
ingredients.addAll([\’gold\’, \’titanium\’, \’xenon\’]);
assert(ingredients.length == 3);
// Adding a duplicate item has no effect.
ingredients.add(\’gold\’);
assert(ingredients.length == 3);
// Remove an item from a set.
ingredients.remove(\’gold\’);
assert(ingredients.length == 2);
使用contains()和containsAll()来检查集合中是否有一个或多个对象:
var ingredients = Set();
ingredients.addAll([\’gold\’, \’titanium\’, \’xenon\’]);
// Check whether an item is in the set.
assert(ingredients.contains(\’titanium\’));
// Check whether all the items are in the set.
assert(ingredients.containsAll([\’titanium\’, \’xenon\’]));
交集是一个集合,其项在另外两个集合中:
var ingredients = Set();
ingredients.addAll([\’gold\’, \’titanium\’, \’xenon\’]);
// Create the intersection of two sets.
var nobleGases = Set.from([\’xenon\’, \’argon\’]);
var intersection = ingredients.intersection(nobleGases);
assert(intersection.length == 1);
assert(intersection.contains(\’xenon\’));
2.2.6 Map
Map API 文档
通常,map 是一个关联键和值的对象。键和值都可以是任何类型的对象。每个键只出现一次,但是您可以多次使用相同的值。dart 对 map 的支持是通过 map 字面量和 map 类型来提供的。(可以看做是混入了 JavaScript 对象字面量写法和 JAVA 的 HashMap 键值的对象)
var gifts = {
// Key: Value
\’first\’: \’partridge\’,
\’second\’: \’turtledoves\’,
\’fifth\’: \’golden rings\’
};
var nobleGases = {
2: \’helium\’,
10: \’neon\’,
18: \’argon\’,
};
注意:
在上面的代码中,解析器推断 gifts 的类型为Map<String, String>,nobleGases 的类型为Map<int, String>。如果您试图向 map 添加错误类型的值,则分析器或运行时将引发错误。
dart 中的 map 和 JavaScript 中的对象是有区别的,键(key)可以是任意数据类型,并且如果是 String 类型的话不能省略引号,因为在 dart 中这样会将其解析为一个变量。
const a = \’1\’;
var map1 = {
true: \’123\’,
a: \’2\’, // 不加引号的a会被解析为\’1\’
b: \’2\’, // 报错,没有b变量
\’a\’: \’2\’
};
同样的,在通过 map 的键获取值得时候,不能使用 JavaScript 中常见的点(.)操作符,只能使用[]操作符,点(.)操作符只能用在获取 dart 中通过类生成的对象的属性或方法中(因为 map 生成的自变量只是看起来和 JavaScript 中的一样,实际上还是有很大差别的) 。
同样可以使用Map构造函数创建对象:
var gifts = new Map();
gifts[\’first\’] = \’partridge\’;
gifts[\’second\’] = \’turtledoves\’;
gifts[\’fifth\’] = \’golden rings\’;
var nobleGases = new Map();
nobleGases[2] = \’helium\’;
nobleGases[10] = \’neon\’;
nobleGases[18] = \’argon\’;
添加值和检索值都如同 JavaScript 中那样进行,不同的是:
如果要获取的键不再 map 中,将会返回一个 null:
var gifts = {\’first\’: \’partridge\’};
assert(gifts[\’fifth\’] == null);
可以使用.length获取 map 中元素的个数:
var gifts = {\’first\’: \’partridge\’};
gifts[\’fourth\’] = \’calling birds\’;
assert(gifts.length == 2);
要创建一个编译时常量的 map 需要在 map 的字面量前加const关键字(或直接使用 const 声明的变量):
var constantMap = const {
2: \’helium\’,
10: \’neon\’,
18: \’argon\’,
};
// OR
const constantMap = {
2: \’helium\’,
10: \’neon\’,
18: \’argon\’,
};
// constantMap[2] = \’Helium\’; // Uncommenting this causes an error.
// 这里不会在编译时报错,但是运行时会抛出异常
2.2.7 Runes(字符)
在 dart 中,字符是字符串的UTF-32编码点。
Unicode 为世界上所有的书写系统中使用的每个字母、数字和符号定义一个唯一的数值。因为 dart 字符串是 UTF-16 代码单元的序列,所以在字符串中表示32位的 Unicode 值需要特殊的语法。
表示 Unicode 码点的常用方法是\\uXXXX,其中 XXXX 是4位数的十六进制值。例如,心型字符(♥)的编码为\\u2665。要指定大于或小于4位十六进制数字,请将值放在花括号中。例如笑脸表情(😆)的编码\\u{1f600}。
String 类有几个属性可以用来获取 runes信息。codeUnitAt 和 codeUnit 属性返回16位代码单元。使用字符属性获取字符串的字符。
下面的示例说明了字符、16位代码单元和32位代码点之间的关系:
main() {
var clapping = \’\\u{1f600}\’;
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));
}
//运行效果如下
😀
[55357, 56832]
[128512]
♥ 😅 😎 👻 🖖 👍
Process finished with exit code 0
注意: 使用列表操作操作 runes 时要小心。根据特定的语言、字符集和操作,这种方法很容易出错。有关更多信息,请参见如何在Dart中反转字符串?
2.2.8 Symbols(符号)
符号对象表示在 dart 程序中声明的操作符或标识符。一般来说可能永远不需要使用符号,但是对于按名称引用标识符的api 来说,它们是非常重要的,因为缩小改变了标识符名称而不是标识符符号。
要获取标识符的符号,请使用符号文字,符号文字仅为#,后面跟着标识符:
#radix
#bar
注意: 符号常量是编译时常量。
2.2.9 枚举类型
枚举类型可以看做是 dart 对类(class)的一种延伸。
使用enum关键字声明一个枚举类型:
enum Color { red, green, blue }
枚举中的每个值都有一个索引 getter,它返回enum声明中值的从0开始的位置。例如,第一个值有索引0,第二个值有索引1。
assert(Color.red.index == 0);
assert(Color.green.index == 1);
assert(Color.blue.index == 2);
使用enum的values常量要获取枚举中所有值的列表。
List<Color> colors = Color.values;
assert(colors[2] == Color.blue);
可以在 switch 语句中使用enum,如果 switch 的 case 不处理enum的所有值,将会报一个警告消息:
var aColor = Color.blue;
switch (aColor) {
case Color.red:
print(\’Red as roses!\’);
break;
case Color.green:
print(\’Green as grass!\’);
break;
default: // Without this, you see a WARNING.
print(aColor); // \’Color.blue\’
}
枚举类型有以下限制:
- 不能子类化、混合或实现枚举。
- 不能显式实例化一个枚举。
以上就是Dart语法之变量声明与数据类型实例详解的详细内容,更多关于Dart变量声明数据类型的资料请关注悠久资源网其它相关文章!
您可能感兴趣的文章:
- FlutterDart快速排序算法示例详解
- Flutter基于DartUnwrappingMultipleOptional小技巧
- SafeList in Flutter and Dart小技巧
- Dart多态控制反转编码规范实例详解
- Dart多个future队列完成加入顺序关系及原子性论证
- Dart 异步编程生成器及自定义类型用法详解
- Flutter入门学习Dart语言变量及基本使用概念
- 一文详解Dart如何实现多任务并行