快学scala第十五章习题答案
- 格式:doc
- 大小:57.50 KB
- 文档页数:12
快速入门Scala编程语言Scala编程语言是一种多范式编程语言,结合了面向对象编程和函数式编程的特点。
它的语法简洁优雅,适合用于大规模的软件开发项目。
本文将带你快速了解Scala编程语言。
一、Scala的基本语法1. 变量和常量:在Scala中,使用关键字`var`来声明一个可变的变量,使用关键字`val`来声明一个不可变的常量。
例如,`var x = 10`声明一个可变变量x,`val y = 5`声明一个不可变常量y。
2. 数据类型:Scala拥有丰富的数据类型,包括整数类型、浮点数类型、布尔类型、字符类型等。
例如,`Int`表示整数类型,`Double`表示浮点数类型,`Boolean`表示布尔类型,`Char`表示字符类型。
3. 控制流语句:Scala支持常见的控制流语句,如条件判断和循环。
例如,`if-else`语句用于条件判断,`for`循环用于迭代执行操作。
4. 函数:在Scala中,函数是一等公民,可以作为值进行传递和操作。
函数的定义使用关键字`def`,例如`def add(x: Int, y: Int): Int = x + y`定义了一个接受两个整数参数并返回它们的和的函数。
5. 类和对象:Scala是一种面向对象的语言,每个值都是一个对象。
类用于定义对象的蓝图,对象是类的实例。
通过使用`class`关键字定义类,使用`new`关键字来创建对象。
二、函数式编程特性Scala内置了许多函数式编程特性,使得函数的组合和操作更加简洁和灵活。
1. 高阶函数:Scala中的函数可以作为值进行传递和操作,因此可以使用函数作为参数或返回值。
这种函数接受其他函数作为参数或将函数作为返回值的函数称为高阶函数。
高阶函数可以极大地简化代码的编写和理解。
2. 不可变性:Scala鼓励使用不可变的数据结构和变量,在处理数据时避免副作用和数据竞争的发生。
不可变性使得代码更加安全和易于调试。
3. 模式匹配:模式匹配是一种强大的功能,用于根据数据的结构和属性进行分支处理。
快学Scala习题解答—第三章数组相关操作3 数组相关操作3.1 编写⼀段代码。
将a设置为⼀个n个随机整数的数组,要求随机数介于0(包括)和n(不包括)之间random和yield的使⽤Scala代码1. import scala.math.random2.3. def randomArray(n:Int)={4. for(i <- 0 until n) yield (random * n).toInt5. }6.7. println(randomArray(10).mkString(","))3.2 编写⼀个循环,将整数数组中相邻的元素置换。
⽐如,Array(1,2,3,4,5)经过置换后变为Array(2,1,4,3,5)对数组⽅法的使⽤Scala代码1. def reorderArray(arr:Array[Int]):Array[Int]={2. val t = arr.toBuffer3. for(i <- 1 until (t.length,2);tmp = t(i);j <- i - 1 until i){4. t(i) = t(j)5. t(j) = tmp6. }7. t.toArray8. }9.10. println(reorderArray(Array(1,2,3,4,5)).mkString(","))3.3 反复前⼀个练习,只是这⼀次⽣成⼀个新的值交换过的数组。
⽤for/yieldScala代码1. def reorderArray(arr:Array[Int]):Array[Int]={2. (for(i <- 0 until (arr.length,2)) yield if (i + 1 < arr.length) Array(arr(i + 1),arr(i)) else Array(arr(i))).flatten.toArray3. }4.5. println(reorderArray(Array(1,2,3,4,5)).mkString(","))3.4 给定⼀个整数数组,产⽣⼀个新的数组,包括元数组中的全部正值,以原有顺序排列,之后的元素是全部零或负值。
cSTL容器适配器习题答案1.概念填空题1.1STL是泛型程序设计的一个良好的范例。
标准C++类库包含的组件既支持面向对象程序设计的设计与编程,又支持泛型程序设计设计。
标准组件对两种设计方法的支持赋予了C++类库复合或双重特性。
1.2构建STL的框架最关键的4个组件是容器、迭代器、算法和函数对象这里算法处于核心地位,迭代器如同算法和容器之间的桥梁,算法通过迭代器从容器中获取元素,然后将获取的元素传递给特定的函数对象进行的操作,最后将处理后的结果储存到容器中。
1.3在C++标准库中包括7种基本容器:向量、双端队列、列表、集合、多重集合、映射和多重映射等。
这7种容器可以分为2种基本类型:顺序和关联1.43种STL容器适配器是栈、队列和优先级队列2.简答题2.1简述STL中迭代子与C++指针的关系与异同点。
2.2在C++标准模板库中,2种容器类型是什么?5种主要迭代器是什么?3种容器适配器是什么?STL算法通过什么来间接访问容器元素?2.3什么是函数对象它的作用是什么,通常用在什么地方如何使用?3.编程题3.1在C++标准模板库中,栈类(tack)的成员函数tack::puh()在栈顶端添加元素,tack:pop()从非空栈的栈顶端中删除一个元素,tack:empty()判断栈是否为空,tack::top()返回非空栈的栈顶元素,tack::ize()返回栈中元素的个数,请构造一个int类型的栈,然后对这个栈调用以上几个函数,体会栈这种数据结构的特点及其成员函数的用法。
#include#include#includeuingnamepacetd;intmain(){inti,a[5]={2,3,5,7,11};tack>ta_vec;for(i=0;i<5;i++){cout<cout<cout<while(!ta_vec.empty()){cout<cout<3.2实际应用中,双端队列比普通队列更加常用。
scala课后习题答案Scala课后习题答案Scala是一种多范式编程语言,它结合了面向对象编程和函数式编程的特性。
在学习Scala的过程中,做课后习题是非常重要的,它可以帮助我们巩固所学的知识,提高编程能力。
下面我们来看一些常见的Scala课后习题及其答案。
1. 编写一个函数,计算给定数组的平均值。
```scaladef average(arr: Array[Int]): Double = {if (arr.isEmpty) 0else arr.sum.toDouble / arr.length}```2. 编写一个函数,将给定的字符串列表连接成一个字符串。
```scaladef concatStrings(strings: List[String]): String = {strings.mkString}```3. 编写一个函数,找出给定数组中的最大值和最小值。
```scaladef findMaxAndMin(arr: Array[Int]): (Int, Int) = {(arr.max, arr.min)}```4. 编写一个函数,将给定的整数列表按照奇偶分成两个列表。
```scaladef splitOddEven(nums: List[Int]): (List[Int], List[Int]) = {nums.partition(_ % 2 == 0)}```5. 编写一个递归函数,计算给定数字的阶乘。
```scaladef factorial(n: Int): Int = {if (n <= 1) 1else n * factorial(n - 1)}```以上是一些常见的Scala课后习题及其答案,通过做这些习题可以帮助我们更好地理解和掌握Scala编程语言。
希望大家在学习Scala的过程中能够多加练习,不断提升自己的编程能力。
11 特质11.1 java.awt.Rectangle类有两个很有用的方法translate和grow,但可惜的是像java.awt.geom.Ellipse2D这样的类没有。
在Scala中,你可以解决掉这个问题。
定义一个RenctangleLike特质,加入具体的translate和grow方法。
提供任何你需要用来实现的抽象方法,以便你可以像如下代码这样混入该特质:val egg = new java.awt.geom.Ellipse2D.Double(5,10,20,30) with RectangleLikeegg.translate(10,-10)egg.grow(10,20)使用自身类型使得trait可以操作x,yimport java.awt.geom.Ellipse2Dtrait RectangleLike{this:Ellipse2D.Double=>def translate(x:Double,y:Double){this.x = xthis.y = y}def grow(x:Double,y:Double){this.x += xthis.y += y}}object Test extends App{val egg = new Ellipse2D.Double(5,10,20,30) with RectangleLikeprintln("x = " + egg.getX + " y = " + egg.getY)egg.translate(10,-10)println("x = " + egg.getX + " y = " + egg.getY)egg.grow(10,20)println("x = " + egg.getX + " y = " + egg.getY)}11.2 通过把scala.math.Ordered[Point]混入java.awt.Point的方式,定义OrderedPoint类。
6 类6.1 改进5.1节的Counter类,让它不要在Int.MaxValue时变成负数6.2 编写一个BankAccount类,加入deposit和withdraw方法,和一个只读的balance属性6.3 编写一个Time类,加入只读属性hours和minutes,和一个检查某一时刻是否早于另一时刻的方法before(other:Time):Boolean。
Time对象应该以new Time(hrs,min)方式构建。
其中hrs以军用时间格式呈现(介于0和23之间)6.4 重新实现前一个类中的Time类,将内部呈现改成午夜起的分钟数(介于0到24*60-1之间)。
不要改变公有接口。
也就是说,客户端代码不应因你的修改而受影响6.5 创建一个Student类,加入可读写的JavaBeans属性name(类型为String)和id(类型为Long)。
有哪些方法被生产?(用javap查看。
)你可以在Scala中调用JavaBeans的getter和setter方法吗?应该这样做吗?javap -c Student 后显示如下6.6 在5.2节的Person类中提供一个主构造器,将负年龄转换为06.7 编写一个Person类,其主构造器接受一个字符串,该字符串包含名字,空格和姓,如new Person("Fred Smith")。
提供只读属性firstName和lastName。
主构造器参数应该是var,val还是普通参数?为什么?必须为val。
如果为var,则对应的此字符串有get和set方法,而Person中的firstName和lastName为只读的,所以不能重复赋值。
如果为var则会重复赋值而报错6.8 创建一个Car类,以只读属性对应制造商,型号名称,型号年份以及一个可读写的属性用于车牌。
提供四组构造器。
每个构造器fc都要求制造商和型号为必填。
型号年份和车牌可选,如果未填,则型号年份为-1,车牌为空串。
《Scala编程》课程作业第⼀题、百元喝酒作业要求:每瓶啤酒2元,3个空酒瓶或者5个瓶盖可换1瓶啤酒。
100元最多可喝多少瓶啤酒?(不允许借啤酒)思路:利⽤递归算法,⼀次性买完,然后递归算出瓶盖和空瓶能换的啤酒数/*** @author DOUBLEXI* @date 2021/8/17 15:33* @description** 作业要求:每瓶啤酒2元,3个空酒瓶或者5个瓶盖可换1瓶啤酒。
100元最多可喝多少瓶啤酒?* (不允许借啤酒)思路:利⽤递归算法,⼀次性买完,然后递归算出瓶盖和空瓶能换的啤酒数*/object HundredBeer {/*** @param sumBeers 啤酒总数* @param bottle 剩余空瓶⼦数量* @param cap 剩余啤酒盖数量* @return 返回总啤酒总数*/def beer(sumBeers: Int, bottle: Int, cap: Int): Int = {println(s"啤酒总数:$sumBeers,剩余空瓶⼦:$bottle,剩余啤酒盖:$cap")// 递归边界条件if (bottle < 3 && cap < 5) return sumBeersvar b1 = bottle / 3 // 现有空瓶⼦能够兑换的啤酒数var b2 = bottle % 3 // 空瓶⼦兑换啤酒后,剩余的空瓶⼦var c1 = cap / 5 // 现有啤酒盖能够兑换的啤酒数var c2 = cap % 5 // 啤酒盖兑换啤酒后,剩余的空瓶⼦/*上⾯⼀顿兑换操作后,啤酒总数为:b1 + c1 + sumBeers剩余的空瓶⼦总数为:b1 + c1 + b2剩余的啤酒盖总数为:b1 + c1 + c2继续递归兑换*/beer(b1 + c1 + sumBeers, b1 + c1 + b2, b1 + c1 + c2)}def main(args: Array[String]): Unit = {var sumBeers: Int = 100 / 2 // 初始化啤酒总数var bottle, cap : Int = sumBeers // 初始化空瓶⼦数=啤酒盖数=啤酒总数val beers = beer(sumBeers, bottle, cap) // 递归求能够喝到的啤酒总数println(s"100元最多可以喝$beers 瓶啤酒")}}运⾏结果如下:第⼆题、⼈机猜拳1.1 作业需求1. 选取对战⾓⾊2. 开始对战,⽤户出拳,与对⼿进⾏⽐较,提⽰胜负信息3. 猜拳结束算分,平局都加⼀分,获胜加⼆分,失败不加分4 . 循环对战,当输⼊“n”时,终⽌对战,并显⽰对战结果5. 游戏结束后显⽰得分如下图所⽰:1.2 作业分析分析业务逻辑,抽象出类、类的属性和⽅法,如下:1. 创建⽤户类User,定义类的属性(name,score)和类的⽅法(showFist())2. 创建计算机类Computer,定义类的属性(name,score)和类的⽅法(showFist())3. 实现计算机随机出拳4. 创建游戏类Game,定义类的属性(甲⽅玩家、⼄⽅玩家、对战次数)5. 编写初始化⽅法、游戏开始⽅法1、编写⽤户类User/*** @author DOUBLEXI* @date 2021/8/17 16:45* @description*//*** ⽤户类User* @param name ⽤户名* @param score ⽤户得分*/class User(var name: String, var score: Int) {var draw: Int = 0 // 平局数var defeat: Int = 0 // 败局数var victory: Int = 0 // 胜局数// 让⽤户⾃⼰出拳,输⼊1.剪⼑ 2.⽯头 3.布def showFist(): Int = {var fist = scala.io.StdIn.readInt()while (fist != 1 && fist != 2 && fist != 3) {println("输⼊不合法,请重新输⼊")fist = scala.io.StdIn.readInt()}return fist}}2、编写电脑类Computer/*** @author DOUBLEXI* @date 2021/8/17 17:09* @description*//*** 电脑类* @param name 电脑名字*/class Computer(var name: String, var score: Int) {var draw: Int = 0 // 电脑平局数var defeat: Int = 0 // 电脑败局数var victory: Int = 0 // 电脑胜局数/*** 随机出拳,1-3* @return 返回⼀个1-3的数字*/def showFist(): Int = {scala.util.Random.nextInt(3) + 1}}3、编写游戏类Game/*** @author DOUBLEXI* @date 2021/8/17 17:11* @description*//*** 游戏类*/class Game {var user: User = _ // 定义玩家var computer: Computer = _ // 定义电脑var battleNum: Int = _ // 定义对战次数/*** 游戏初始化⽅法*/def gameInit(): Unit = {val motd ="""------------------欢迎进⼊游戏世界-----------------****************************************************猜拳开始*******************************************************""".stripMarginprintln(motd) // 打印游戏欢迎信息println("请选择对战⾓⾊:(1.刘备 2.关⽻ 3.张飞)") // ⽤户选择电脑的⾓⾊var roleNum = scala.io.StdIn.readInt()while (roleNum != 1 && roleNum != 2 && roleNum != 3) {println("没有这个选项,请重新输⼊!")roleNum = scala.io.StdIn.readInt()}val battleRole = roleNum match {case 1 => "刘备"case 2 => "关⽻"case 3 => "张飞"}println(s"你选择了与${battleRole}对战")user = new User("游客", 0) // 初始化玩家信息computer = new Computer(s"$battleRole", 0) // 初始化电脑信息battleNum = 0 // 初始化对战信息}/*** 游戏主程,游戏开始⽅法* 循环对战,直到输⼊n终⽌*/def startGame(): Unit = {var isExist = falsevar isStartNext: Char = 'y'// 循环对战while (!isExist) {battleNum += 1; // 对战次数+1// 玩家出拳println("请出拳!1.剪⼑ 2.⽯头 3.布")var userFist = user.showFist()userFist match {case 1 => println("你出拳:剪⼑")case 2 => println("你出拳:⽯头")case 3 => println("你出拳:布")}// 电脑出拳println(s"${}出拳!")var computerFist = computer.showFist()computerFist match {case 1 => println(s"${}出拳:剪⼑")case 2 => println(s"${}出拳:⽯头")case 3 => println(s"${}出拳:布")}// 调⽤judge⽅法,判断胜负judge(userFist, computerFist)// 根据⽤户输⼊判断是否开启下⼀轮游戏,n退出println("是否开始下⼀轮(y / n)")isStartNext = scala.io.StdIn.readChar()while (isStartNext != 'n' && isStartNext != 'N' && isStartNext != 'Y' && isStartNext != 'y') { println("您的输⼊不正确,请重新输⼊!")isStartNext = scala.io.StdIn.readChar()}if (isStartNext =='n'|| isStartNext == 'N') isExist = true}println("退出游戏!")// 打印得分成绩echoResult}* 判断猜拳胜负* @param userFist ⽤户出拳* @param computerFist 电脑出拳*/def judge(userFist: Int, computerFist: Int): Unit = {val judgeNum = userFist match {case 1 => if (computerFist == 1) 0 else if (computerFist == 2) -1 else 1case 2 => if (computerFist == 1) 1 else if (computerFist == 2) 0 else -1case 3 => if (computerFist == 1) -1 else if (computerFist == 2) 1 else 0}if (judgeNum == 0) {println("结果:和局!下次继续努⼒!")user.score += 1user.draw += 1computer.score += 1computer.draw += 1} else if (judgeNum == 1) {println("结果:恭喜,你赢啦!")user.score += 2user.victory += 1computer.defeat += 1} else {println("结果:你输了,下次继续努⼒!")user.defeat += 1computer.victory += 1}}/*** 打印得分成绩*/def echoResult(): Unit = {println("---------------------------------------------------------")println(s"${} VS ${}")println(s"对战次数${battleNum}次")println()println()println("姓名\t等分\t胜局\t和局\t负局")println(s"${}\t${user.score}\t\t${user.victory}\t\t${user.draw}\t\t${user.defeat}")println(s"${}\t${computer.score}\t\t${computer.victory}\t\t${computer.draw}\t\t${computer.defeat}") }}/*** 游戏主程⼊⼝*/object Game {def main(args: Array[String]): Unit = {val game = new Game // 定义⼀个游戏对象game.gameInit() // 游戏初始化println("要开始么?y/n")var isStart = scala.io.StdIn.readChar()while (isStart != 'Y' && isStart != 'y' && isStart != 'n' && isStart != 'N') {println("没有这个选项,请重新输⼊!")isStart = scala.io.StdIn.readChar()}// 开始游戏if (isStart == 'Y' || isStart == 'y') game.startGame}}运⾏结果如下:不合法输⼊:打印得分:第三题、⽤户位置时长统计现有如下数据需要处理:字段:⽤户ID,位置ID,开始时间,停留时长(分钟)4⾏样例数据:UserA,LocationA,8,60UserA,LocationA,9,60UserB,LocationB,10,60UserB,LocationB,11,80样例数据中的数据含义是:⽤户UserA,在LocationA位置,从8点开始,停留了60钟处理要求:1、对同⼀个⽤户,在同⼀个位置,连续的多条记录进⾏合并2、合并原则:开始时间取最早时间,停留时长累计求和答:算法如下:1、定义⼀个样例类,⽤于存储每个⽤户的浏览数据* 定义⼀个样例类:装载⽤户时长数据* @param userName ⽤户名* @param location ⽤户位置* @param startTime ⽤户开始浏览时间* @param duration ⽤户本次浏览时长*/case class UserInfo(userName:String, location:String, startTime:Int, duration:Int)2、在object主程序⾥,定义⼀个列表,⽤于存储各个⽤户的浏览信息。
16 注解16.1 编写四个JUnit测试用例,分别使用带或不带某个参数的@Test注解。
用JUnit执行这些测试import org.junit.Testclass ScalaTest {@Testdef test1(){print("test1")}@Test(timeout = 1L)def test2(){print("test2")}}16.2 创建一个类的示例,展示注解可以出现的所有位置。
用@deprecated作为你的示例注解。
@deprecatedclass Test{@deprecatedval t = _;@deprecated(message = "unuse")def hello(){println("hello")}}@deprecatedobject Test extends App{val t = new Test()t.hello()t.t}16.3 Scala类库中的哪些注解用到了元注解@param,@field,@getter,@setter,@beanGetter 或@beanSetter?看Scala注解的源码就OK了16.4 编写一个Scala方法sum,带有可变长度的整型参数,返回所有参数之和。
从Java调用该方法。
import annotation.varargsclass Test{@varargsdef sum(n:Int*)={n.sum}}public class Hello {public static void main(String[] args){Test t = new Test();System.out.println(t.sum(1,2,3));}}16.5 编写一个返回包含某文件所有行的字符串的方法。
从Java调用该方法。
import io.Sourceclass Test{def read()={Source.fromFile("test.txt").mkString}}public class Hello {public static void main(String[] args){Test t = new Test();System.out.println(t.read());}}16.6 编写一个Scala对象,该对象带有一个易失(volatile)的Boolean字段。
让某一个线程睡眠一段时间,之后将该字段设为true,打印消息,然后退出。
而另一个线程不停的检查该字段是否为true。
如果是,它将打印一个消息并退出。
如果不是,则它将短暂睡眠,然后重试。
如果变量不是易失的,会发生什么?这里只有一个线程修改Boolean字段,所以字段是否为volatile应该是没有区别的import scala.actors.Actorclass T1(obj:Obj) extends Actor{def act() {println("T1 is waiting")Thread.sleep(5000)obj.flag = trueprintln("T1 set flag = true") }}class T2(obj:Obj) extends Actor{ def act() {var f = truewhile (f){if(obj.flag){println("T2 is end")f = false}else{println("T2 is waiting") Thread.sleep(1000)}}}}class Obj{// @volatilevar flag : Boolean = false}object Test{def main(args: Array[String]) {val obj = new Obj()val t1 = new T1(obj)val t2 = new T2(obj)t1.start()t2.start()}}16.7 给出一个示例,展示如果方法可被重写,则尾递归优化为非法import annotation.tailrecclass Test{@tailrecdef sum2(xs:Seq[Int],partial:BigInt) :BigInt = {if (xs.isEmpty) partial else sum2(xs.tail,xs.head + partial)}}编译报错,修改如下import annotation.tailrecobject Test extends App{@tailrecdef sum2(xs : Seq[Int],partial : BigInt) : BigInt = {if (xs.isEmpty) partial else sum2(xs.tail,xs.head + partial)}println(sum2(1 to 1000000,0))}16.8 将allDifferent方法添加到对象,编译并检查字节码。
@specialized注解产生了哪些方法?object Test{def allDifferent[@specialized T](x:T,y:T,z:T) = x != y && x!= z && y != z}javap Test$得到public final class Test$extends ng.Object{public static final Test$MODULE$;public static {};public boolean allDifferent(ng.Object, ng.Object, ng.Object);public boolean allDifferent$mZc$sp(boolean, boolean, boolean);public boolean allDifferent$mBc$sp(byte, byte, byte);public boolean allDifferent$mCc$sp(char, char, char);public boolean allDifferent$mDc$sp(double, double, double);public boolean allDifferent$mFc$sp(float, float, float);public boolean allDifferent$mIc$sp(int, int, int);public boolean allDifferent$mJc$sp(long, long, long);public boolean allDifferent$mSc$sp(short, short, short);public boolean allDifferent$mVc$sp(scala.runtime.BoxedUnit, scala.runtime.BoxedUnit, scala.runtime.BoxedUnit);}16.9 Range.foreach方法被注解为@specialized(Unit)。
为什么?通过以下命令检查字节码: javap -classpath /path/to/scala/lib/scala-library.jar scala.collection.immutable.Range并考虑Function1上的@specialized注解。
点击Scaladoc中的Function1.scala链接进行查看首先来看Function1的源码......trait Function1[@specialized(scala.Int, scala.Long, scala.Float, scala.Double/*, scala.AnyRef* /) -T1, @specialized(scala.Unit, scala.Boolean, scala.Int, scala.Float, scala.Long, scala.Doubl e/*, scala.AnyRef*/) +R]extends AnyRef { self =>/** Apply the body of this function to the argument.* @return the result of function application.*/def apply(v1: T1): R......可以看到Function1参数可以是scala.Int,scala.Long,scala.Float,scala.Double,返回值可以是scala.Unit,scala.Boolean,scala.Int,scala.Float,scala.Long,scala.Double 再来看Range.foreach的源码......@inline final override def foreach[@specialized(Unit) U](f:Int => U) {if (validateRangeBoundaries(f)) {var i = startval terminal = terminalElementval step = this.stepwhile (i != terminal) {f(i)i += step}}}......首先此方法是没有返回值的,也就是Unit。
而Function1的返回值可以是scala.Unit,scala.Boolean,scala.Int,scala.Float,scala.Long,scala.Double 如果不限定@specialized(Unit),则Function1可能返回其他类型,但是此方法体根本就不返回,即使设置了也无法获得返回值16.10 添加assert(n >= 0)到factorial方法。
在启用断言的情况下编译并校验factorial(-1)会抛异常。
在禁用断言的情况下编译。
会发生什么?用javap检查该断言调用object Test {def factorial(n:Int): Int = {assert(n > 0)n}def main(args:Array[String]) {factorial(-1)}}编译报错Exception in thread "main" ng.AssertionError: assertion failedat scala.Predef$.assert(Predef.scala:165)at Test$.factorial(Test.scala:6)at Test$.main(Test.scala:11)at Test.main(Test.scala)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:2 5)at ng.reflect.Method.invoke(Method.java:597)at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120) 禁用assert-Xelide-below 2011反编译此类javap -c Test$ 得到......public int factorial(int);Code:0: getstatic #19; //Field scala/Predef$.MODULE$:Lscala/Predef$;3: iload_14: iconst_05: if_icmple 128: iconst_19: goto1312: iconst_013: invokevirtual #23; //Method scala/Predef$.assert:(Z)V16: iload_117: ireturn ......。