7、函数式编程
以下示例,都通过开发有理数为示例。以下代码与函数式编程没有啥关系:
packagecn.wangjian
objectDemo06_Function {
defmain(args: Array[String]): Unit = {
valrational: Rational =newRational(2,3);//输出:2/3
valrational2: Rational =newRational(2,3);
valrational3: Rational = rational.add(rational2);
println(rational3);
}
classRational(r: Int, d: Int) {
require(d !=)
//必须要满足这个条件,否则将异常退出
private valnumber: Int = r;
private valdenom: Int = d;
override deftoString:String=number+"/"+denom;
//添加add方法
defadd(that: Rational): Rational = {
newRational(this.number* that.denom+ that.number*this.denom,
this.denom* that.denom);
}
}
}
1、自引用
自引用是指this关键字,同时this关键字,又可以被省略。
//获取较大的值
defmax(that: Rational): Rational ={
if(this.lessThan(that)) thatelse this
}
//比较
deflessThan(that: Rational): Boolean = {
//2/3 lessThan 1/2 = 2*2=4 > 1*3所以得出2/3大于1/2
this.number* that.denomnumber*this.denom
}
2、辅助构造方法(auxiliary-constructor)
1:可以使用this(..)定义更多的构造方法。但主构造方法,必须要被调用。
2:辅助构造方法,必须以def this(..)开始。必须先调用同一个类中的另一个构造,即必须是this(..)的形式。
声明有多个构造的类:
classStud(n:String, a: Int) {
private varname:String= n;
//成员变量没有办法与局部变量重名了
private varage: Int = a
//构造.必须只能调用this(..)
def this(n:String) =this(n, -1)
//构造
def this(a: Int) =this("noname", a)
//自动生成的toString
override deftoString =s"Stud($name,$age)"
}
实例化测试:
packagecn.wangjian
objectDemo07_Constructor {
defmain(args: Array[String]): Unit = {
valstud: Stud =newStud("Jack",44);
valstud2: Stud =newStud("Jack");
valstud3: Stud =newStud(44);
println(stud +","+ stud2 +","+ stud3)
}
}
更多构造方法的调用过程:
1、私有字段和方法
使用private关键字,可以声明私有的成员变量和方法。默认情况下,如果没有使用任何的修饰符号,将使用public做为修饰符号。
具体代码,略。
//求两个数的最大公约数
private defgcd(a: Int, b: Int): Int = {
if(b ==) aelsegcd(b, a % b)
}
4、定义操作符号
可以通过定义操作符号将x.add(y)写成x+y,更直观。
//定义操作符号
def+ (that:Rational):Rational={
add(that)
}
测试调用操作符号:
valrational4:Rational=rational+rational2;
println("使用+操作符号的:"+rational4)
5、隐式转换
用于实现更多兼容的一种代码实现。
通过定义隐式转换,就可以实现:
rational+1即加个int类型或是Long类型的功能。
packagecn.wangjian
/**
*另一种开发APP的方法
*/
objectDemo05_AppextendsApp {
//在这儿定义隐匿转换
//定义隐式转换,因为这儿要用隐匿转换,所以必须要将隐式转换放到这儿定义到Rational类中不可行
implicit defintToRational(x: Int) =newRational(x);
//为了接收Long类型,还给Rational定义了一个接收Long类型的构造方法
implicit deflongToRational(x: Long): Rational =newRational(x)
//测试
varr1: Rational =newRational(1,2);
varr2: Rational =newRational(1,2);
varr3: Rational =r1+r2;
varr4: Rational =r1+1;
varr5: Rational =r1+2L;
//测试
println(r3)
println(r4)
println(r5)
}
8、内建的控制结构
只人为数不多的内建控制结构:
If、while、for、try、match。
这些内建的控制结构,都有返回值,即函数式编程。
1、for..yield
for 循环中的 yield 会把当前的元素记下来,保存在集合中,循环结束后将返回该集合。Scala 中 for 循环是有返回值的。如果被循环的是 Map,返回的就是 Map,被循环的是 List,返回的就是 List,以此类推。
示例:
以下是一个普通的遍历:
scala> for(i
以下是将i的值通过yield放入一个集合:
scala> for(i
还可以在yield中对元素进行计算:
scala> for(i
scala> for(i
使用yield遍历集合:
scala> val arr:Array[String] = Array("Jack","Mary","Rose")
arr: Array[String] = Array(Jack, Mary, Rose)
scala> for(a
res7: Array[String] = Array(Jack, Mary, Rose)
2、过虑filter
可以在for循环中,使用一个,或是多个if对数据进行过虑。
使用if条件
scala> val arr:Array[String] = Array("Jack","Mary","Rose","Alex")
arr: Array[String] = Array(Jack, Mary, Rose, Alex)
scala> for(a
res0: Array[String] = Array(Jack, Mary)
使用多个if条件
scala> for(a
res3: Array[String] = Array()
3、for..to
使用to关键字,两边为闭区间,to表示
scala> for(i
scala> for(i
| println(i)
| }
4、for..until
until为开区间,不包含结束的值。以下结果,最大值为4,所以,until表示
scala> for(i
5、异常处理
1、抛出异常
Throw关键字,用于抛出异常。
defmm(n: Int): Int = {
if(n %2==)
n
else
throw newRuntimeException("不是2的倍数")
}
2、捕获异常
可以在catch中使用case处理异常,然后处理。
defex(n: Int): Int = {
vara:Int = -1
try{
a =100/ n;
}catch{
caseex: ArithmeticException => {
println("运算错误:"+ ex.getMessage)
throwex
}
caseex:Exception=> {
println("其他错误:"+ ex.getMessage)
throwex
}
}
returna//必须要返回一个值,否则异常
}
Scala并不需要你捕获受检查的异常,也不需要你使用throws关键字,来声明异常。不过,还是可以使用@throws注解,来声明一个throws子句,来声明有可能的异常,但这并不是必须的。关于注解,以后再讲。
3、finally
与Java代码一样,finally里面包含了必须要执行的代码。
defex(n: Int): Int = {
vara:Int = -1
try{
a =100/ n;
}catch{
caseex: ArithmeticException => {
println("运算错误:"+ ex.getMessage)
throwex
}
caseex:Exception=> {
println("其他错误:"+ ex.getMessage)
throwex
}
}finally{
println("最后必须要执行的代码...")
}
returna//必须要返回一个值,否则异常
}
6、match表达式
Scala中的match表达式,让你从若干可选项目中选择,就像是switch语句那样。
Scala中提供了比java,c更加强大的switch语句——match,而且不用担心因为忘记写break语句而发生case穿透。
scala> def say(age:Int):Int= age match{
| case 10=>10
| case 20=>20
| case 30=>30
| case _ =>100
| }
say: (age: Int)Int
scala> say(30)
res9: Int = 30
scala> say(40)
res10: Int = 100
scala> say(100)
res11: Int = 100
7、不再使用break和containue关键字
Scala中没有break和continue关键字。
用if来替换containue和用boolean来替换break。
以下示例就是用if来替换containue:
packagecn.wangjian
/**
*可以使用if语句来替换掉containue
*/
objectDemo13_IfContainue {
defmain(args: Array[String]): Unit = {
for(i
if(i%2==){
println(i);
}
}
}
}
可以使用boolean来替换break:
/**
*用Boolean来替换掉Break
*/
objectDemo14_BooleanBreak {
defmain(args: Array[String]): Unit = {
varboo: Boolean =true
vari =;
while(i
i+=1
if(i >=10) {
boo =false//设置为false以后即会停止循环
}
println(i)
}
}
}
领取专属 10元无门槛券
私享最新 技术干货