3.4 方法

Dart是一个面向对象的语言,其特性之一为一切皆对象。因此,一个方法(也称为函数)也是一个对象,而且具有一种类型,即Function。故它可以赋值给某个变量,也可以当作其他方法中的某个参数,还可以当作方法调用Dart类的一个实例。

3.4.1 定义一个方法

声明一个方法:

img
img

观察上面的代码,开头的int是静态类型定义,表示执行这个方法将会得到一个int型的结果。静态类型定义可以省略,但是为了保证具有更好的可读性,建议加上它。

对于像上述简单到只有一个表达式的方法,可以简写为

img

其中,“=>”语法等同于return,有时称其为箭头语法。在箭头语法和最后结尾的分号之间只能使用表达式,不能使用语句。

3.4.2 参数

方法的参数包括必选参数和可选参数两种。

1.必选参数

在参数列表中,必选参数在最前面,可选参数随后。代码如下:

img

这和上面声明一个方法的代码类似,只是在小括号中加了一个参数列表,即String(也可以写成var)类型的name和var(也可以写成int)类型的age。在方法体中,输出一个字符串就需要上述两个参数。在调用这个方法时,IDE会自动提示需要给定这两个参数值,即这两个值为必选参数。一个典型的方法调用如下所示:

img

运行结果:

img

需要注意,参数在方法体中的引用方式需要使用“$”。

2.可选参数

在Dart中,可选参数分为可选命名参数和基于位置的参数,二者是互斥关系,不能同时出现。声明一个带有可选命名参数的方法十分简单,参考下面的代码:

img
img

和之前声明一个方法的示例不同,这次在小括号内添加了一个可选命名参数,其结构是“属性名:值”,并用大括号包裹。在调用此类方法时,由于参数可选,因此需要指明给定的值是属于哪一个参数的。

一个可选位置参数和之前讲过的拼接字符串类似,先来看以下代码片段:

img

将参数放置在中括号中,便成了可选位置参数。在调用此方法时,只需如下代码即可:

img

运行结果:

img

最后,做一个测试。如果在调用上面的方法时,不传递任何参数值,即如下的写法,会有怎样的输出?

img

输出结果:

img

这显然不是理想的结果,对于不知道名字的用户,或许需要一个默认值,输出类似“您好,欢迎您的使用”的欢迎词,而不是用null。那么,怎样去定义这个默认值呢?我们可以对sayWelcome()方法稍加修改,代码片段如下:

img

运行结果:

img

这就是为某个参数定义默认值的方法,对于可选命名参数和可选位置参数来讲都一样。

3.4.3 主方法

在Dart中,main()方法即主方法。主方法表示程序从这个方法的方法体中开始执行,因此,也称为入口函数。

main()方法返回void(即没有返回值),以及一个可选的参数List<String>。

一般来讲,在Visual Studio Code中输入main时,IDE的自动提示功能会出现提示下拉列表,其中包含main()方法。

3.4.4 作用域

Dart是静态作用域语言,变量的作用域通常在其定义时就确定了。一个简单的判断依据是查找距离它最近的大括号,因为一个变量的作用域只能在大括号所包裹的范围中访问。代码片段如下:

img

上述代码中的倒数第二行(print(scope_b))会被报错,无法编译。这是因为名为scope_b的变量,其作用域只作用于scopeTestInner()方法中,故倒数第二行的print(scope_b)“看不到”scope_b变量,因此会出现编译错误。但和scope_b不同,scope_a变量作用域覆盖整个scopeTest()方法,而scopeTestInner()方法又被scopeTest()方法包含,因此在scopeTestInner()方法内可以正常使用scope_a,因为程序能够“看到”它。

3.4.5 闭包

所谓闭包,即方法的对象,即无论该方法对象在何处被调用,该对象总是可以访问其作用域内的变量。对之前声明带有必选参数的方法稍加改造,如下:

img

其中,name和age两个变量的作用域在这个方法内,即无论它们在哪里被调用,在方法内始终可用。

3.4.6 检查两个方法是否相等

检查两个方法是否相等和判断两个变量是否相等类似,都是采用连等号(==)来判断,代码如下:

img

在上述代码中,由于leftSide()方法和rightSide()方法的返回值都是5,因此在最后的判断中结果将输出true。

3.4.7 返回值

在Dart中,当一个方法没有声明返回类型和return语句时,将默认为return null;否则,将按照代码中指定的返回类型作为返回值。