[Flutter]足够入门的Dart语言系列之函数:函数定义、调用、5种参数类型和main函数

简介: 函数(Function)也被称为方法(Method)。其最直观的理解就是数据中的函数,比如y=f(x),在编程中,f对输入x进行处理,返回结果y,就是一个函数......

函数(Function)也被称为方法(Method)。其最直观的理解就是数据中的函数,比如y=f(x),在编程中,f对输入x进行处理,返回结果y,就是一个函数。

接受输入,逻辑处理,返回结果。这是一切编程的本质,所有的程序都是这样的处理模型,无非是输入的内容不同,或逻辑处理的规则不同,或返回的表现形式不同,以实现不同的功能或效果。

函数本质上是完成一定功能的代码块,通过将一段代码包装为函数,可以在需要的时候进行调用,完成要想的功能。

比如下面的代码块,用于完成加法的功能,放在了名为add的函数内,这就是一个完成的函数:

int add(int x, int y){
    return x+y;
}

当用到加法功能时,直接调用add函数即可。

print(add(1,2)); // 输出 3

Dart是一个真正面向对象的语言,所以,即便函数也是对象,其类型为Function。这就意味着,函数可以和普通的对象(变量数据)一样使用,可以被赋值、可以作为函数参数。

函数的定义

dart中定义一个函数的基本结构如下,如果函数没有返回值,则返回值类型 为 void

返回值类型 函数名(参数类型 参数名){
   函数体;
}
void是一种特殊的类型,表示一个值永远不会被使用。 void 常用于声明函数的返回类型,表示没有返回值。

比如,一个计算平方的函数:

int square(int x) {
  return x * x;
}

比如,还是上面的加法函数:

int add(int a ,int b ) {
  int c = a + b; // 赋值语句
  return c; // 返回语句
}

add为函数名,前面的类型为函数的返回类型,后续括号内的变量为参数,{}大括号内的为函数体,即代码执行的主体。

dart中,返回值类型 和 参数类型 可以省略【但极其不推荐】

函数的简写(箭头形式)

函数支持箭头形式的简写,当函数体只有一行表达式时,可以通过=>简写表示返回表达式的值。

int square(int x) => x * x;
int add(int a ,int b ) => a + b;

void add2(int a ,int b ) => a + b;
=>expr{ return expr; } 的简写。 =>后面的只能是表达式而非语句

函数的调用

函数调用时通过函数名、(),加上传入的参数,即可执行一个函数。如下执行一个函数并将其返回值赋值给一个变量:

var result = add(1,2);

函数的参数

函数的参数分为命名参数、默认参数、位置参数、可选的位置参数等几种类型。

无参数函数

无参数函数没有任何参数。

下面的getInt方法用于获取一个0~9的数字,没有任何参数。

import 'dart:math';

// 获取一个数字
int getInt(){
  var random = new Random();
  return random.nextInt(10);
}

位置参数

位置参数是最常见参数形式,每个参数以列表的形式位于()内,调用时,也是根据位置,一个个的传入参数。

比如上面的add函数add(1,2);

定义一个求幂的函数:

int myPower(int num, int power) {
  var result = 1;
  for (int i = 0; i < power; i++) {
    result *= num;
  }
  return result;
}

调用时,需要按照位置传入参数,位置不同,函数的执行结果就会不一样。

print(myPower(3, 2)); // 9
print(myPower(2, 3)); // 8

命名参数(可选)

使用{类型1 参数1, 类型2 参数2, …}的形式来指定命名参数。命名参数默认是可选参数,也就是参数不是必须的,调用时可以不指定。如果希望命名参数必须传入,则需要指定required标记。

命名参数的好处是,通过名称表示当前参数,使语义更加明确,知道指定的参数是哪个,而不像位置参数,需要通过函数定义或注释,才能知道哪个参数是什么含义;而且,命名参数是无顺序的,这样就不用按照固定顺序传入参数,尤其在参数非常多的时候,这非常方便,直接参数名语义化表示。

比如求幂的函数改为命名参数:

int myPower({
  required int num,
  required int power
}) {
  var result = 1;
  for (int i = 0; i < power; i++) {
    result *= num;
  }
  return result;
}

命名参数的调用,通过参数名:值的形式进行传参。明确传入对应的参数:

print(myPower(num: 3, power: 2));
print(myPower(power: 2, num: 3));

可以看到,无论传入的顺序,通过参数名指定值,明确的表示求数字32次幂。

由于命名参数是可选参数,因此参数可以不传入,那么,就要保证参数可为空,或者有一个默认值。

比如上面的myPower函数,如果不标记requirednumpower又不能为空,可选不传入时就无法赋值null,因此就会有如下错误:参数不能为null值。

为其指定required或默认值,下面默认求数字的平方:

int myPower({
   required int num,
   int power=2
}) {
  var result = 1;
  for (int i = 0; i < power; i++) {
    result *= num;
  }
  return result;
}

调用时,可选指定参数:

print(myPower(num: 3));  // 9

可选的位置参数

使用 [] 将一系列参数包裹起来作为可选的位置参数,既然是可选的,则可选的不用指定参数入参。

可选的位置参数必须按照参数位置传入,作为可选参数,其值必须是可为null的,否则必须有一个默认值。

int myPower2(int num,[ int power=2]) {
  var result = 1;
  for (int i = 0; i < power; i++) {
    result *= num;
  }
  return result;
}

调用方式,和普通的多参数函数一样:

print(myPower2(5));     //  25
print(myPower2(5,6));   //  15625

DateTime类的构造函数就是可选位置参数最典型的应用,其中必须传入 year 参数。之后的参数为可选位置参数,是选填的,但必须按照顺序进行填写。

DateTime(int year,
      [int month = 1,
      int day = 1,
      int hour = 0,
      int minute = 0,
      int second = 0,
      int millisecond = 0,
      int microsecond = 0])
DateTime(2022,10);
DateTime(2035,10,10);

默认参数

在可选的命名参数和可选的位置参数中,可以使用=为参数指定默认值。表示在未指定此参数时,所使用的默认值。{类型 参数名 = 默认值}

默认值必须为编译时常量,没有指定默认值的情况下默认值为 null。

上面的示例中,已经演示了默认参数的情况:int myPower({ required int num, int power=2 })int myPower2(int num,[ int power=2])

main函数

每个 Dart 程序都必须有一个 main() 顶级函数作为程序的入口。

main() 函数返回值为 void 并且有一个 List<String> 类型的可选参数。

void main() {
  print('Hello, World!');
}

List<String>作为参数时,主要接收程序启动时传入的参数,比如命令行传入的选项。

void main(List<String> arguments) {
  print(arguments);
}

返回值

Dart中所有函数都有返回值。

通过return语句可以显式的返回一个对象。没有返回语句的函数最后一行默认为执行 return null;

foo() {}

print(foo() == null); // true

参考

Dart 开发语言概览-函数参数

相关文章
|
2月前
|
Dart
如何在 Flutter 项目中使用 Dart 语言?
如何在 Flutter 项目中使用 Dart 语言?
127 58
|
18天前
|
Dart
flutter dart mixin 姿势
flutter dart mixin 姿势
|
15天前
|
Dart 安全 编译器
Flutter结合鸿蒙next 中数据类型转换的高级用法:dynamic 类型与其他类型的转换解析
在 Flutter 开发中,`dynamic` 类型提供了灵活性,但也带来了类型安全性问题。本文深入探讨 `dynamic` 类型及其与其他类型的转换,介绍如何使用 `as` 关键字、`is` 操作符和 `whereType&lt;T&gt;()` 方法进行类型转换,并提供最佳实践,包括避免过度使用 `dynamic`、使用 Null Safety 和异常处理,帮助开发者提高代码的可读性和可维护性。
67 1
|
1月前
|
Dart 开发者 Windows
flutter:dart的学习
本文介绍了Dart语言的下载方法及基本使用,包括在Windows系统上和VSCode中的安装步骤,并展示了如何运行Dart代码。此外,还详细说明了Dart的基础语法、构造函数、泛型以及库的使用方法。文中通过示例代码解释了闭包、运算符等概念,并介绍了Dart的新特性如非空断言操作符和延迟初始化变量。最后,提供了添加第三方库依赖的方法。
28 12
|
1月前
|
开发框架 移动开发 Android开发
安卓与iOS开发中的跨平台解决方案:Flutter入门
【9月更文挑战第30天】在移动应用开发的广阔舞台上,安卓和iOS两大操作系统各自占据半壁江山。开发者们常常面临着选择:是专注于单一平台深耕细作,还是寻找一种能够横跨两大系统的开发方案?Flutter,作为一种新兴的跨平台UI工具包,正以其现代、响应式的特点赢得开发者的青睐。本文将带你一探究竟,从Flutter的基础概念到实战应用,深入浅出地介绍这一技术的魅力所在。
74 7
|
3月前
|
Dart JavaScript 前端开发
Dart或Flutter中解决异常-type ‘int‘ is not a subtype of type ‘double‘
Dart或Flutter中解决异常-type ‘int‘ is not a subtype of type ‘double‘
128 4
|
3月前
|
Kubernetes Cloud Native 搜索推荐
探索云原生技术:Kubernetes入门与实践打造个性化安卓应用:从零开始的Flutter之旅
【8月更文挑战第31天】云原生技术正改变着应用开发和部署的方式。本文将带你了解云原生的基石——Kubernetes,通过实际的代码示例,从安装到部署一个简单的应用,让你迅速掌握Kubernetes的核心概念和操作方法。无论你是初学者还是有一定经验的开发者,这篇文章都将成为你进入云原生世界的桥梁。
|
3月前
|
Dart 开发工具
消除Flutter doctor的警告Warning: `dart` on your path resolves to xxx/bin/dart
消除Flutter doctor的警告Warning: `dart` on your path resolves to xxx/bin/dart
67 0
|
1月前
|
Android开发 iOS开发 容器
鸿蒙harmonyos next flutter混合开发之开发FFI plugin
鸿蒙harmonyos next flutter混合开发之开发FFI plugin
|
28天前
|
开发者
鸿蒙Flutter实战:07-混合开发
鸿蒙Flutter混合开发支持两种模式:1) 基于har包,便于主项目开发者无需关心Flutter细节,但不支持热重载;2) 基于源码依赖,利于代码维护与热重载,需配置Flutter环境。项目结构包括AppScope、flutter_module等目录,适用于不同开发需求。
69 3