开发者社区> 代码迷途> 正文

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

简介: 函数(Function)也被称为方法(Method)。其最直观的理解就是数据中的函数,比如y=f(x),在编程中,f对输入x进行处理,返回结果y,就是一个函数......
+关注继续查看
福利推荐:阿里云、腾讯云、华为云等大品牌云产品全线2折优惠活动来袭,4核8G云服务器899元/3年,新老用户共享优惠,点击这里立即抢购>>>

函数(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 开发语言概览-函数参数

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Flutter如何调试应用【Dart Observatory 】以及调试模式断言
Flutter如何调试应用【Dart Observatory 】以及调试模式断言
112 0
Flutter(三)——一篇文章掌握Dart语言的用法(三)
Flutter(三)——一篇文章掌握Dart语言的用法(三)
82 0
Flutter(三)——一篇文章掌握Dart语言的用法(一)
Flutter(三)——一篇文章掌握Dart语言的用法(一)
102 0
Flutter(三)——一篇文章掌握Dart语言的用法(二)
Flutter(三)——一篇文章掌握Dart语言的用法(二)
88 0
[Flutter]足够入门的Dart语言系列之面向对象:类之间的6大关系
无论是面向对象编程,还是面向过程、函数式编程,代码与代码之间的组织关系都是最重要的。通过代码的编写、代码间的相互调用、不同代码的合理使用、集合不同的数据和方法,才能...
62 0
[Flutter]足够入门的Dart语言系列之面向对象:类成员的可见性、常量和工厂构造函数详解
类和成员的可见性,这在基于库或包的开发中非常重要,Dart中提供了工厂构造函数,可以方便的实现单例、缓存实例对象、返回子类等,以及常量构造函数的使用......
47 0
[Flutter]足够入门的Dart语言系列之面向对象:类的定义详解、成员和实例使用
类表示的是分类,一类问题或事物,它是对具体或现实世界的抽象。比如动物类、犬科动物类、猫科动物类、房子类、数学类,类是具体事物的描述,它不是指具体的某个动物、某栋房子、某个数学题,而是对它们的概括...
57 0
[Flutter]足够入门的Dart语言系列之函数:匿名函数、作用域闭包、类型别名和内联函数类型
函数在Dart中是对象,因此,可以将函数作为参数传递给另一个函数、作为一个'值'赋值给一个变量。下面主要介绍匿名函数、内联函数类型的使用,以及了解下作用域和闭包...
122 0
[Flutter]足够入门的Dart语言系列之常见运算符或操作符
Dart中的运算符提供对数据操作和处理的能力,其中的算术运算符、逻辑运算符非常符合现实中的使用情况,其他不同的运算符则有着自己的操作逻辑...
85 0
[Flutter]足够入门的Dart语言系列之流程控制语句:中断和异常(continue/break、try...catch)
循环的执行是通过循环条件来控制的,但是,有时我们想要通过额外的条件判断,来决定是否中断执行,或者中断本次循环而继续执行下次及之后的循环;此外,我们需要对于异常情况的处理...
79 0
+关注
文章
问答
文章排行榜
最热
最新
相关电子书
更多
Flutter企业级应用开发实战手册
立即下载
Flutter技术解析与实战
立即下载
Flutter in action
立即下载


http://www.vxiaotou.com