【Dart】002-函数

文章目录

  • ​​【Dart】002-函数​​
  • ​​〇、学习启动器 1.0​​
  • ​​一、函数是什么​​
  • ​​0、概述​​
  • ​​像一个黑箱​​
  • ​​数学意义​​
  • ​​1、编程中的函数与方法​​
  • ​​强调的是功能/作用​​
  • ​​完成特定功能的代码段​​
  • ​​2、函数的定义​​
  • ​​语法格式​​
  • ​​简单演示​​
  • ​​省略 `返回值类型` 和 `参数类型` (不推荐)​​
  • ​​3、函数的简写:箭头函数​​
  • ​​代码演示​​
  • ​​二、函数的参数与调用​​
  • ​​0、概述​​
  • ​​1、多个参数​​
  • ​​代码演示​​
  • ​​运行结果​​
  • ​​2、命名参数的作用​​
  • ​​语义更加明确​​
  • ​​无需按照参数顺序进行传递​​
  • ​​3、默认参数​​
  • ​​概述​​
  • ​​语法格式​​
  • ​​代码演示​​
  • ​​运行结果​​
  • ​​4、位置参数​​
  • ​​概述​​
  • ​​代码演示​​
  • ​​运行结果​​
  • ​​三、函数类型​​
  • ​​0、概述​​
  • ​​1、函数对象的声明和使用​​
  • ​​代码演示​​
  • ​​运行结果​​
  • ​​有什么好处​​
  • ​​2、函数类型方法参数​​
  • ​​把函数作为其他函数的参数​​
  • ​​直接提供一个匿名函数​​
  • ​​完整代码演示​​
  • ​​运行结果​​
  • ​​3、函数的作用​​

〇、学习启动器 1.0

第一步:煮茶(茶包 + 少量茶叶)

第二步:按摩仪按摩眼部 10 分钟;

第三步:倒茶 + 戴上耳机听纯音乐 + 倒计时 10 分钟 + 加告诉自己随时可以停止学习

第四步:后面每 25 分钟为一个周期,每 25 分钟休息 5 分钟,随时可以停止这个循环

注意点:不追求学习的速度,不安排任何学习任务,随时可以停止学习!

一、函数是什么

0、概述

像一个黑箱

函数像一个黑箱,不同的输入,会通过黑箱中的逻辑处理产生一个对应的输出

数学意义

输入是 ​​自变量 x​​​ , 输出是 ​​因变量 y​​​ ,其中黑箱的处理逻辑称为对应法则 ​​f ​​​。三者的关系可以通过 ​​y = f(x)​​ 来表示。

1、编程中的函数与方法

强调的是功能/作用

数学中的 ​​函数​​​ 是强调两个 ​​集合​​ 间的映射关系,这对于编程中的函数而言,还是有区别的。编程中并不强制输入和输出的数量,​​function​​​ 更强调的是 ​​作用​​​ 和 ​​功能​​​ ,其目的是完成特定的 ​​任务​​,而非仅是维护映射关系。

完成特定功能的代码段

在 ​​c/c++​​ 中一般称一个功能团(完成特定功能的代码段)为 ​​函数 function​​​ ,在 ​​java​​​ 的类中,一般称一个功能团为 ​​方法 method​​ 。它们都是完成特定任务的代码段。

2、函数的定义

在 ​​dart​​ 中,定义函数并不需要关键字。

语法格式

返回值类型 方法名(参数类型 参数名){
方法体;
}

简单演示

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

省略 返回值类型 和 参数类型 (不推荐)

square(x) {
return x * x;
}

3、函数的简写:箭头函数

当函数体中只要一行表达式时,可以通过 ​​=>​​ 进行简写,返回表达式的值!

闲聊*:这种写法和 ​​ts​​​ 是一样的,​​java​​​ 的箭头函数是 ​​->​​​ ,我的日常工作中,写习惯了前端,忽然写 ​​java​​ 代码会不习惯。虽然我是一个以后端为主的程序员,但在前端花费的时间常常更多!

代码演示

int square(int x) => x * x;

二、函数的参数与调用

0、概述

不同的编程语言有不同的参数特性,对于 ​​Dart​​​ 而言,支持 ​​命名参数​​​ 、​​位置参数​​​ 、​​默认参数​​ ,总的来说还是比较丰富的。

闲聊*:各种参数带来了编程的灵活性,​​java​​ 在这方面我觉得就比较欠缺,很多时候我很喜欢带默认值的参数!

1、多个参数

代码演示

void solution(int n, int m) {
print("头数:$n 足数:$m");
int y = (m - n * 2) ~/ 2;
int x = n - y;
print("雉数:$x 兔数:$y");
}

void main() {
solution(35, 94);
}

运行结果

头数:35  足数:94
雉数:23 兔数:12

2、命名参数的作用

语义更加明确

它可以使 ​​语义更加明确​​​ ,在函数定义时,通过 ​​{}​​ 可以设为命名参数。

调用函数的时候:solution(head: 35, foot: 94);

闲聊*:确实是语义明确了,但是也增加了代码量,我在编写 ​​java​​​ 代码时使用的 ​​IntelliJ IDEA​​ 是带提示的!

void solution({
required int head,
required int foot,
}) {
print("头数:$head 足数:$foot");
int y = (foot - head * 2) ~/ 2;
int x = head - y;
print("雉数:$x 兔数:$y");
}

void main() {
solution(head: 35, foot: 94);
}

无需按照参数顺序进行传递

闲聊*:表面意思,这个好像有点用吧!毕竟都是命名参数了,只要写了肯定能对应上。

void solution({
required int head,
required int foot,
}) {
print("头数:$head 足数:$foot");
int y = (foot - head * 2) ~/ 2;
int x = head - y;
print("雉数:$x 兔数:$y");
}

void main() {
// 不用按顺序写
solution(foot: 94, head: 35);
}

3、默认参数

概述

在命名参数中设置参数的默认值

语法格式

{类型 参数名 = 默认值}

代码演示

void solution({
// 此处不能使用 required 关键字,都有默认值了,所以不传参数也可以
int number = 10
}) {
print(number);
}

void main() {
// 带参数调用
solution(number: 35);
// 不带参数调用
solution();
}

运行结果

35
10

4、位置参数

概述

位置参数通过 ​​[参数1,参数2,...]​​​ 来指定,其特点是必须​​按顺序​​依次进行指定若干入参。正是因为这种特性,一般来说用于参数有前后顺序的场景

代码演示

void main() {
print(DateTime(1996, 4, 27));
}

运行结果

1996-04-27 00:00:00.000

三、函数类型

0、概述

函数可以通过 ​​typedef​​​ 定义类型,如下定义了一个 ​​Operation​​​ 类型,表示一种入参是 ​​double​​​ ,返回值是 ​​double​​ 的函数。

typedef Operation = double Function(double);

闲聊*:这种东西挺新的!在 ​​ts​​​ 中有类似的东西!​​ts​​​ 的调用签名(我的 ​​ts​​ 学得并不好!)。

1、函数对象的声明和使用

代码演示

// 函数类型
typedef Operation = double Function(double);

// 函数
double square(double a) {
return a * a;
}

main(){
// 函数对象定义
Operation op = square;
// 调用函数对象:下面两种写法效果一样!
// 和直接调用 square 函数的效果一样!
print(op(2));
print(op.call(2));
}

运行结果

4.0
4.0

有什么好处

通过函数类型,可以让我们把函数当做 ​​对象​​​ 来看待,这就表示 ​​op​​ 变量可以在编程中指代其他符合方法签名的其他函数。

哦!方法签名!哈哈!具体使用时的强大作用,可能要在具体使用的时候去体会了!

// 函数类型
typedef Operation = double Function(double);

// 函数
double square(double a) {
return a * a;
}

// 函数
double cube(double a) {
return a * a * a;
}

main(){
// 函数对象定义
Operation op = square;
// 调用函数对象:下面两种写法效果一致
print(op(2));
print(op.call(2));

Operation op1 = cube;
print(op1(2));
print(op1.call(2));
}
// 4.0
// 4.0
// 8.0
// 8.0

2、函数类型方法参数

把函数作为其他函数的参数

函数既然可以当做 ​​对象​​ 看待,那自然就可以作为函数的入参,这也是函数类型的价值体现

其中 ​​?​​ 表示该入参可为空。

下面并不是一定要用 ​​{}​​ 这只是命名参数写法罢了!

double add(double a, double b, {Operation? op}) {
if (op == null) return a + b;
return op(a) + op(b);
}

直接提供一个匿名函数

直接提供一个函数,那么就不用传这个参数了!

double add(double a, double b, op: (double e) => e * e) {
if (op == null) return a + b;
return op(a) + op(b);
}

完整代码演示

// 函数类型
typedef Operation = double Function(double);

// 函数
double square(double a) {
return a * a;
}

// 函数
double cube(double a) {
return a * a * a;
}

double add(double a, double b, Operation? op) {
if (op == null) return a + b;
return op(a) + op(b);
}

main(){
// 函数对象定义
Operation op = square;
// 调用函数对象:下面两种写法效果一致
print(op(2));
print(op.call(2));

Operation op1 = cube;
print(op1(2));
print(op1.call(2));

print(add(2, 4, square));
}

运行结果

4.0
4.0
8.0
8.0
20.0

3、函数的作用

函数本质上是对实现某特定功能的代码段的封装,以实现共享。这种共享有利有弊,好处在于,普通的开发者即使能力不强,也可以通过引入三方库,或者复制粘贴来完成功能需求。这就大大降低了编程中实现功能的门槛,也有利于集中人类智慧去共同解决一些问题。**弊在于,**理想很丰满,显示很骨感。就像吃大锅饭一样,这会导致很大一批人,过于依赖别人,缺乏自主思考的能力,当出现问题或找不到库时,就举步维艰。