Scala函数

文章目录

  • 一、第1关:方法
  • S 三角形 ​
    • 实验代码:
  • 二、第2关:Scala函数以及函数调用
    • 实验代码:


一、第1关:方法

任务描述
本关任务:根据三角形的三边长 a、b、c,返回三角形的面积。

任意三角形面积公式-海伦公式

已知三角形三边a、b、c,则

S
三角形

p(p−a)(p−b)(p−c)

p=
2
1

(a+b+c)

相关知识
为了完成本关任务,你需要掌握:

什么是方法;

方法的使用。

方法
定义函数最常用的方式是作为某个对象的成员。这种函数被称为方法(method)。换句话来说在类中定义的函数即是方法。

定义方法的基本格式是:

def 方法名称 (参数列表):返回值类型 = 方法体
如果你不写等于号和方法主体,那么方法会被隐式声明为抽象(abstract),包含它的类型也将是一个抽象类型。

方法定义由一个 def 关键字开始,接着为该方法的名称,紧接着是可选的参数列表(意味着可写可不写),一个冒号 : 和方法的返回类型,一个等于号 = ,最后是方法的主体。

接着我们来看几个定义方法的示例:

参数列表为空,返回类型为 Unit 的方法:

def f1() : Unit = {
println(“f1”)
}
返回 Unit 类型的函数,但是没有显式指定返回类型。(当然也可以返回非 Unit 类型的值):

def f2() = {
println(“f2”)
}
如果参数列表有多个时,可以使用逗号连接,当用 return 进行返回时,方法中必须明确指定返回值类型:

def addInt( a:Int, b:Int ) : Int = {
var sum:Int = 0
sum = a + b
return sum
}
返回值类型有多种可能,此时也可以省略 Unit:

def f3(content: String) = {
if(content.length >= 3)
content + “喵喵喵~”
else
3
递归方法必须明确指定方法返回值类型:

def factorial(n: Int): Int = {
if(n <= 0)
1
else
n * factorial(n - 1)
}
方法的最简形式:

def m = 100
方法的调用
Scala 提供了多种不同的方法调用方式:

直接通过方法名(参数列表)调用:

functionName( 参数列表 )
如果方法使用了实例的对象来调用,我们可以使用类似 Java 的格式 (使用 . 号):

[instance.]functionName( 参数列表 )
这里我们主要介绍第一种:

示例:

object Test {
def main(args: Array[String]) {
println( "Returned Value : " + addInt(5,7) );
}
def addInt( a:Int, b:Int ) : Int = {
var sum:Int = 0
sum = a + b
return sum
}
}
执行结果:

Returned Value : 12
注意:当方法没有参数列表或参数列表为空时,调用该方法时可以省略方法后的括号。

编程要求
仔细阅读右侧编辑区内给出的代码框架及注释,在 Begin-End 间编写程序代码,定义一个 area 方法,该方法具有三个参数,类型都是 Int 型,分别代表三角形的三条边长,返回值类型为 Double;要求根据三角形的三边长,返回三角形的面积。

测试说明
平台将使用测试集运行你编写的程序代码,若全部的运行结果正确,则通关。

例:
测试输入:

3
4
5
预期输出:

三角形的面积为:6.00

实验代码:

import scala.io.StdInobject Triangle {/********** Begin *********/def area(a: Int, b: Int, c: Int): Double = {   val s = (a + b + c) / 2.0    math.sqrt(s * (s - a) * (s - b) * (s - c))  }  /********** End *********/def main(args: Array[String]): Unit = {val a: Int = StdIn.readInt()val b: Int = StdIn.readInt()val c: Int = StdIn.readInt()printf("三角形的面积为:%.2f", area(a, b, c))}
}

在这里插入图片描述

二、第2关:Scala函数以及函数调用

任务描述
本关任务:计算小明请完 5 顿饭之后还剩多少钱。

相关知识
为了完成本关任务,你需要掌握:

什么是函数;
如何调用函数。
函数定义
Scala 作为支持函数式编程的语言,Scala 函数式编程是 Scala 的重中之重,高级函数也是其独特的一个特性。首先,函数/变量同是一等公民,函数与变量同等地位,函数的定义可以单独定义,可以不依赖于类、接口或者 object,可以独立存在、独立使用,并且可以赋值给变量。

我们上一关所学习的方法就是函数的一种形式。接下来我们来看函数的定义:

(函数的参数列表)=>{函数体内容}
由于该函数需要被别人调用,所以要用一个变量来引用。

val 变量名称 =(函数的参数列表)=>{函数体内容}
示例:

// 将 x 的值加 1
val increase = (x:Int) => x+1
=> 表示该函数将左侧的内容(任何整数 x)转换成右侧的内容(x+1)。

因此,这是一个将任何整数 x 映射成 x+1 的函数。

复杂的定义形式:

val 变量名称:(输入参数类型) => 返回值类型 =(输入参数的引用)=>{函数体内容}
示例:

// 计算 x 和 y 的和
val add: (Int, Int) => Int = (x:Int, y:Int)=> x+y
如果你想要在函数中包含多于 1 条语句,可以将函数体用花括号括起来,每条语句占一行,组成一个代码块(block)。跟方法一样,当函数值被调用时,所有的语句都会被执行,并且该函数的返回值就是对最后一个表达式求值的结果。

参数列表对于方法是可选的,但是对于函数是强制的。

方法可以没有参数列表,参数列表也可以为空。但是函数必须有参数列表(参数列表可以为空)。

而函数可以直接赋值给变量,可以让函数很方便的传递。

函数调用
传值调用和传名调用
Scala 的解释器在解析函数参数(function arguments)时有两种方式:

传值调用(call-by-value):先计算参数表达式的值(reduce the arguments),再应用到函数内部;

传名调用(call-by-name):将未计算的参数表达式直接应用到函数内部。

object Test {
def main(args: Array[String]): Unit = {
callByValue(something())
println(“------------------------------”)
callByName(something())
}

def something() = {
println(“calling something”)
}
def callByValue(x: Int) = {
println(“x1=” + x)
println(“x2=” + x)
}
def callByName(x: => Int) = {
println(“x1=” + x)
println(“x2=” + x)
}
}
执行结果:

calling something
x1=1
x2=1


calling something
x1=1
calling something
x2=1
从执行结果上来看,我们可以得出:

在进入函数内部前,传值调用方式就已经将参数表达式的值计算完毕,而传名调用是在函数内部进行参数表达式的值计算的。

这就造成了一种现象,每次使用传名调用时,解释器都会计算一次表达式的值。

指定函数参数名调用
一般情况下函数调用参数,就按照函数定义时的参数顺序一个个传递。但是我们也可以通过指定函数参数名,并且不需要按照顺序向函数传递参数。

object Test {
def main(args: Array[String]) {
printInt(7,5); // 默认按参数顺序调用
println(“------------------------------”)
printInt(b=5, a=7); // 指定函数参数名调用
}
def printInt( a:Int, b:Int ) = {
println("Value of a : " + a );
println("Value of b : " + b );
}
}
执行结果:

Value of a : 7
Value of b : 5


Value of a : 7
Value of b : 5
注意:当参数列表为空时,直接写方法名可以调用方法,而函数名只是代表函数对象本身。因为保存函数字面量的变量(又称为函数名或者函数值)本身就是实现了 FunctionN 特质的类的对象,要调用对象的 apply 方法,就需要使用obj()的语法。所以函数名后面加括号才是调用函数。如下:

如果我们想要直接操纵方法的话,可以使用下划线(_)将方法转换为函数。

object TestMap {
def ttt(f:Int => Int):Unit = {
val r = f(10)
println®
}
val f0 = (x : Int) => x * x
//定义了一个方法
def m0(x:Int) : Int = {
//传递进来的参数乘以10
x * 10
}
//将方法转换成函数,利用了神奇的下滑线
val f1 = m0 _
def main(args: Array[String]): Unit = {
ttt(f0)
//通过m0 _将方法转化成函数
ttt(m0 _)
// 如果直接传递的是方法名称,scala相当于是把方法转成了函数
ttt(m0)
}
}
编程要求
仔细阅读右侧编辑区内给出的代码框架及注释,在 Begin-End 间编写程序代码,计算小明请完 5 顿饭之后还剩多少钱。具体要求如下:

变量 money 定义了小明的钱数,初始值为 1000 元;

eat 方法中定义了每请一顿饭消耗多少元;

balance 方法实现计算小明还剩多少元的功能;

定义一个 printMoneyByValue 方法,该方法传名调用 balance 函数,类型为 Int 的参数,打印连续五次调用所给参数后,小明还剩多少元;

定义一个 printMoneyByName 方法,该方法传值调用 balance 函数,类型为 Int 的参数,打印连续五次调用所给参数后,小明还剩多少元;

输出格式:“你的余额现在为:xx”,xx 为剩余钱数。

测试说明
平台将使用测试集运行你编写的程序代码,若全部的运行结果正确,则通关。

例:
测试输入:无
预期输出:

你的余额现在为:950


你的余额现在为:650

实验代码:

object Test {var money = 1000// 吃一顿消费50def eat(): Unit = {money = money - 50;}// 余额def balance(): Int = {eat()money}/********** Begin *********/def printMoneyByValue(balanceFunc: => Int): Unit = {  val currentMoney = balanceFunc  println(s"你的余额现在为:$currentMoney")  }  def printMoneyByName(mealCost: Int): Unit = {    for (_ <- 1 to 5) {  eat()   }val remainingMoney = money  println(s"你的余额现在为:$remainingMoney")    }  /********** End *********/def main(args: Array[String]): Unit = {printMoneyByValue(balance())println("-------------------")printMoneyByName(balance())}}

在这里插入图片描述


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/29240.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

外网怎么访问内网?

当我们需要在外网环境下访问内网资源时&#xff0c;常常会面临一些困扰。通过使用一些相关的技术与工具&#xff0c;我们可以轻松地实现这一目标。本文将介绍如何通过【天联】组网产品&#xff0c;解决外网访问内网的问题。 【天联】组网是一款由北京金万维科技有限公司自主研…

JAVAFX打包部署真正能用的办法(jdk21,javafx23)IntelliJ IDEA

我之前创建了javafx项目&#xff0c;想打包试试。一试&#xff0c;全是坑&#xff0c;所以记录下来&#xff0c;为有缘人节约时间。直接构建工件是错误的&#xff0c;别尝试了&#xff0c;找不在JDK的。我也花了一天多的时间尝试了网上各种大神的办法&#xff0c;就没找到一个是…

算法 Hw9

Hw 9 1 Scheduling with profits and deadlines12345 2 Parallel machine1234 1 Scheduling with profits and deadlines 1 决策问题表述&#xff1a; 给定一个利润值 P P P&#xff0c;是否存在一个任务调度方案使得完成所有任务的总利润至少为 P P P 2 在 NP 类中&…

stm32学习-软件I2C读取MPU6050

接线 SDAPB11SCLPB10 I2C 对操作端口的库函数进行封装 void MyI2C_W_SCL(uint8_t BitValue)//写 {GPIO_WriteBit(GPIOB, GPIO_Pin_10, (BitAction)BitValue);Delay_us(10); }void MyI2C_W_SDA(uint8_t BitValue)//写 {GPIO_WriteBit(GPIOB, GPIO_Pin_11, (BitAction)BitValu…

Redis 7.x 系列【4】命令手册

有道无术&#xff0c;术尚可求&#xff0c;有术无道&#xff0c;止于术。 本系列Redis 版本 7.2.5 源码地址&#xff1a;https://gitee.com/pearl-organization/study-redis-demo 文章目录 1. 说明2. 命令手册2.1 Generic2.2 数据类型2.2.1 String2.2.2 Hash2.2.3 List2.2.4 S…

docker入门——镜像命令、容器命令及其他常用命令

镜像命令 dockers images [-a | -q] 查看镜像 -a: 显示所有细腻些 -q: 只显示镜像ID docker search [–filter]搜索命令 –filter字段值 docker pull 镜像名[:tag] 下载镜像不加tag默认下载最新镜像 docker rmi [options] 删除镜像 ​ -f 容器ID [,容器ID&#xff0c;容…

如何在纯内网环境下,将EasyCVR视频汇聚网关通过4G与第三方公网云平台级联?

EasyCVR视频汇聚网关是TSINGSEE青犀软硬一体的一款产品&#xff0c;可提供多协议的接入、音视频采集、处理&#xff0c;能实现海量前端设备的轻量化接入/转码/分发、视频直播、云端录像、云存储、检索回看、智能告警、平台级联等&#xff0c;兼容多种操作系统&#xff0c;轻松扩…

HTTP/2 协议学习

HTTP/2 协议介绍 ​ HTTP/2 &#xff08;原名HTTP/2.0&#xff09;即超文本传输协议 2.0&#xff0c;是下一代HTTP协议。是由互联网工程任务组&#xff08;IETF&#xff09;的Hypertext Transfer Protocol Bis (httpbis)工作小组进行开发。是自1999年http1.1发布后的首个更新。…

速盾:海外网站cdn加速免费

随着互联网的快速发展和全球化的趋势&#xff0c;海外网站的重要性也日益增加。然而&#xff0c;由于地理位置等各种因素的限制&#xff0c;海外访问海外网站的速度往往较慢&#xff0c;给用户的体验带来了不便。为了解决这个问题&#xff0c;许多网站开始采用CDN加速技术。 C…

HTML 实体字符简介

在网页设计与开发中&#xff0c;HTML 实体字符扮演着重要的角色&#xff0c;它们帮助我们在HTML文档中安全地插入特殊字符&#xff0c;避免浏览器解析时产生错误或意外的布局效果。实体字符通过特定的编码方式来表示&#xff0c;使得浏览器能够正确识别并展示这些特殊字符。下面…

在云服务器上安装配置和调优Zerotier服务器的详细教程

Hey&#xff0c;朋友们&#xff01;今天我要在服务器上部署和调优Zerotier服务器。使用三丰云提供的免费服务器&#xff0c;配置为1核CPU、1G内存、10G硬盘和5M带宽。虽然配置不高&#xff0c;但三丰云的免费云服务器已经足够应付我们今天的项目。&#x1f44d; Zerotier服务器…

阻塞锁和自旋锁的理解

阻塞锁和自旋锁的理解 文章目录 阻塞锁和自旋锁的理解阻塞锁自旋锁阻塞锁自旋锁各自的优缺点自旋锁阻塞锁 选择自旋锁还是阻塞锁 想象你和你的朋友们一起玩一个游戏&#xff0c;但是每次只能一个人玩。为了决定谁先玩&#xff0c;你们可以用两种方法来排队&#xff1a; 阻塞锁…

小程序-生命周期(2) 应用周期/页面周期

一.应用周期 应用周期指的是小程序&#xff1a;启动->运行->销毁的整个过程。 应用周期伴随一些函数来进行控制&#xff0c;这些函数卸载app.js里面的App方法里。 分别由onLaunch&#xff0c; onShow&#xff0c;onHide依次进行。 onLaunch&#xff1a;初始化的时候运行…

第3讲:关于Pixi的Text、Container、Sprite、Graphics组件功能作用

首先这里提供一个公用代码&#xff1a; 下部分各种组件基于这个公用代码直接往下添加代码即可。 import {Application, Text, Container, Sprite, BaseTexture, Texture, Graphics} from pixi.js import ./style.css import testImageUrl from ./images/test.jpg // 指明Appli…

3.1、前端异步编程(超详细手写实现Promise;实现all、race、allSettled、any;async/await的使用)

前端异步编程规范 Promise介绍手写Promise&#xff08;resolve&#xff0c;reject&#xff09;手写Promise&#xff08;then&#xff09;Promise相关 API实现allraceallSettledany async/await和Promise的关系async/await的使用 Promise介绍 Promise是一个类&#xff0c;可以翻…

HTML静态网页成品作业(HTML+CSS)—— 家乡成都介绍网页(4个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;未使用Javacsript代码&#xff0c;共有4个页面。 二、作品演示 三、代…

【玩转google云】实战:如何在GKE上使用Helm安装和配置3节点的RabbitMQ集群

需求 因项目需要需要在Google Kubernetes Engine (GKE) 中使用Helm安装一个3节点的RabbitMQ集群,配置用户名和密码,开通公网访问的Web管理界面,指定namespace为mq,并使用5G的硬盘存储MQ的数据。 前提条件 GKE集群:确保你有一个运行中的GKE集群。Helm工具:确保已安装Hel…

Qt 插件框架

在Qt框架中实现插件系统主要涉及到使用Qt的插件机制来动态加载和卸载插件模块。 1、定义插件接口 首先&#xff0c;你需要定义一个或多个接口类&#xff0c;这些类将作为插件和主程序之间的契约。这些接口类通常包含纯虚函数&#xff0c;插件需要实现这些函数。 // MyPlug…

C语言 | Leetcode C语言题解之第164题最大间距

题目&#xff1a; 题解&#xff1a; int maximumGap(int* nums, int numsSize) {if (numsSize < 2) {return 0;}int maxVal INT_MIN, minVal INT_MAX;for (int i 0; i < numsSize; i) {maxVal fmax(maxVal, nums[i]);minVal fmin(minVal, nums[i]);}int d fmax(1,…

计算机网络:3数据链路层

数据链路层 概述封装成帧和透明传输帧透明传输&#xff08;填充字节或比特&#xff09;差错检测奇偶校验循环冗余校验CRC Cyclic Redundancy Check 可靠传输停止-等待协议回退n帧协议&#xff08;滑动窗口协议&#xff09;选择重传协议 点对点协议PPP共享式以太网网络适配器&am…