一个最基本的 Dart 程序
下面的代码使用了很多 Dart
中最基本的特性:
// 定义个方法。
printNumber(num aNumber) {
print('The number is $aNumber.'); // 在控制台打印内容。
}
// 这是程序执行的入口。
main() {
var number = 42; // 定义并初始化一个变量。
printNumber(number); // 调用一个方法。
}
注意:无返回值的时候void写不写都OK
下面是上面代码中使用的一些可以应用到几乎所有 Dart 应用中的特性:
- //
使用 //
表示后面的文字都是注释。 另外,你还可以使用/* … */
。
- int
一种类型,Dart
语言有自己的内嵌类型,如:String
, List
, bool
是另外几种类型。
- 42
一个数字字面量。数字字面量是编译时常量。
一种打印内容的方法。
- $aNumber
字符串插值:在字符串字面量中引用变量或者表达式,也可以使用${expression}
- main()
Dart
程序执行的入口方法,每个程序都需要一个这样的方法。 更多详细 The main() function.
- var
一种不指定类型声明变量的方式。
注意: 我们的代码准守 Dart 代码样式中的规则。 例如: 我们使用两个空格来缩进代码。
重要的概念
在学习 Dart
的时候,请牢记下面一些事实和概念:
所有能够使用变量(variable)引用的都是对象(object), 每个对象都是一个类的实例。在
Dart
中 甚至连数字(numbers
)、方法(functions
)和null
都是对象。所有的对象都继承于 Object 类。Dart
是强类型语言,类型的标注是可选的,Dart
会自动推测类型。在上面的代码中num
被推测为int
类型。如果不确定类型,使用dynamic
Dart
支持泛型,像数组List<int>
(a list of integers) 或者List<dynamic>
(a list of objects of any type).Dart 支持顶级方法 (例如
main()
),同时还支持在类中定义函数。 (静态函数和实例函数)。 你还可以在方法中定义方法 (嵌套方法或者局部方法)。同样,
Dart
还支持顶级变量(top-level variables
),以及在类中定义变量(静态变量和实例变量)。 实例变量有时候被称之为域(fields
)或者属性(properties
)。和 Java 不同的是,
Dart
没有public
、protected
、 和private
等关键字。如果一个标识符以(_)
开头,则该标识符在库内是私有的。详情请参考: 库和可见性。
标识符可以以字母或者 _ 下划线开头,后面可以是其他字符和数字的组合。
Dart
有 表达式 expression 和 语句 statement。比如:条件表达式condition ? expr1 : expr2
拥有值expr1
和expr2
。对比if-else statement,这里没有值。但是语句经常包含一个或者多个表达式,但是表达式不能包含语句。
-
Dart
工具可以指出两种问题:警告和错误( warnings and errors)。 警告只是说你的代码可能有问题, 但是并不会阻止你的代码执行。 错误可以是编译时错误也可以是运行时错误。遇到编译时错误时,代码将 无法执行;运行时错误将会在运行代码的时候导致一个 异常。
关键字(Keywords)
下表是Dart
中的关键字
应该避免使用这些关键字作为标识符,然而,如果有需要,关键词中带有上标的可以作为标识符
关键词中上标为1的是上下文关键词(contextual keywords),用于具体的地方。它们是可以用于任何地方是有效的标识符
关键词中上标为2的是内嵌标识符(built-in identifiers)。 这些关键字是为了方便把
JavaScript
代码移植到Dart
而存在的,可以用于大多数地方,但是不能用于类(class
)或类型名(type names
),或者作为前缀倒入(import prefixes
)关键词中上标为3是在 Dart 1.0 发布以后又新加的,用于 支持异步相关的特性。 你不能在标记为
async
、async*
、或者sync*
的方法体内使用async
、await
、或者yield
作为标识符。 详情请参考:异步支持
所以其他单词都是保留词。 你不能用保留词作为关键字。
变量(Variables)
下面是声明变量并赋值的示例:
var name = 'Bob';
变量是一个引用。上面名字为 name
的变量引用了 一个内容为 “Bob” 的String
对象。
name
变量的类型被自动推测为String
,但是我们能够指定具体的类型来修改它的类型。如果对象并没有被限制为单一类型,可以指定为 Object
或者dynamic
类型,更多了解design guidelines.
dynamic name = 'Bob';
另外一种可选方式就是显示声明变量类型
String name = 'Bob';
默认值(Default value)
Uninitialized variables have an initial value of null. Even variables with numeric types are initially null, because numbers—like everything else in Dart—are objects.
没有初始化的变量有一个默认值为null
。甚至类型为数字的变量如果没有初始化其值也是null
,因为数字(numeric
)类型也是对象。
int lineCount;
assert(lineCount == null);
注意:在生产模式 assert()
语句被忽略了。在检查模式 assert(*condition*)
会执行,如果条件不为 true 则会抛出一个异常。详情请参考 Assert 部分。
Final和const
如果你从未打算修改一个变量,使用final
或者 const
,而不是使用var
或者类型。 一个final
变量只能赋值一次;一个 const
变量是编译时常量。 (Const
变量是隐式的 final
变量。) 顶级的final
变量或者类中的final
变量在第一次使用的时候初始化。
注意: 实例变量可以为
final
但是不能是const
。final
实例变量必须在类的构造器中进行初始化,更多了解initializer list
下面是final
变量的示例:
final name = 'Bob'; // Without a type annotation
final String nickname = 'Bobby';
我们不能修改final
变量的值
name = 'Alice'; // Error: a final variable can only be set once.
const
变量为编译时常量,可以直接定义const
和其值。 如果const
变量是在类中,请定义为 static const
。static
用于修饰成员变量,表示这个变量是属于类的,而不是属于对象的
const bar = 1000000; // Unit of pressure (dynes/cm2)
const double atm = 1.01325 * bar; // Standard atmosphere
const
关键字不仅仅只用来定义常量。 有可以用来创建常量值, 还能定义构造函数为const
类型的,这种类型的构造函数创建的对象是不可改变的。任何变量都可以有常量值。
var foo = const [];
final bar = const [];
const baz = []; // Equivalent to `const []`
我们能够在初始化表达式的时候省略const
关键字,比如上面的baz
foo = [1, 2, 3]; // Was const []
所以我们不能修改baz
baz = [42]; // Error: Constant variables can't be assigned a value.
总结final和const的区别
final
:表示单一赋值,final
变量或字段必须初始化。 一旦赋值,就不能改变final
变量的值。 final
修饰变量
const
的含义在Dart中有点复杂和微妙。
const
修饰值,可以在创建集合时使用它,例如const [1,2,3]
,以及构造对象(代替new),比如const Point(2,3)
。这里,const意味着对象的整个深度状态可以在编译时完全确定,并且对象将被冻结并完全不可变。更多有关两者区别可以看 ''const'' and ''final'' keyword in Dart
对于更多信息有关于 const
来创建常量值 Lists, Maps, and Classes.