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 ### 实验代码: ```python import scala.io.StdIn object 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)) } } ``` ![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/d6a55841aaa74bdababc2eea289bf56e.png) ## 二、第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 ### 实验代码: ```python object Test { var money = 1000 // 吃一顿消费50 def 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()) } } ``` ![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/e32bb1f0876a4f82ab4ac2cc3960b221.png) *** ** * ** ***

相关推荐
旷世奇才李先生2 分钟前
Next.js 安装使用教程
开发语言·javascript·ecmascript
凛铄linshuo22 分钟前
爬虫简单实操2——以贴吧为例爬取“某吧”前10页的网页代码
爬虫·python·学习
牛客企业服务25 分钟前
2025年AI面试推荐榜单,数字化招聘转型优选
人工智能·python·算法·面试·职场和发展·金融·求职招聘
charlie11451419137 分钟前
深入理解Qt的SetWindowsFlags函数
开发语言·c++·qt·原理分析
胡斌附体37 分钟前
linux测试端口是否可被外部访问
linux·运维·服务器·python·测试·端口测试·临时服务器
likeGhee1 小时前
python缓存装饰器实现方案
开发语言·python·缓存
whoarethenext1 小时前
使用 C++/Faiss 加速海量 MFCC 特征的相似性搜索
开发语言·c++·faiss
项目題供诗2 小时前
黑马python(二十五)
开发语言·python
读书点滴2 小时前
笨方法学python -练习14
java·前端·python
慌糖2 小时前
RabbitMQ:消息队列的轻量级王者
开发语言·javascript·ecmascript