Scala语言学习笔记——方法、函数及异常
1.Scala 方法及函数区别
① Scala 有方法与函数,二者在语义上的区别很小。Scala 方法是类的一部分,而函数是一个对象可以赋值给一个变量。换句话来说在类中定义的函数即是方法
② Scala 中的方法跟 Java 的类似,方法是组成类的一部分
③ Scala 中的函数则是一个完整的对象,Scala 中的函数其实就是继承了 Trait 的类的对象
④ Scala 中使用 val 语句可以定义函数,def 语句定义方法和函数
class Test {
def method (x: Int) = x + 3
val function = (x: Int) => x + 3
}
2.Scala 方法
① 方法的声明语法
基本语法
def 方法名 ([参数名: 参数类型], ...)[[: 返回值类型] =] {
语句...
return 返回值
}
说明:[ ] 表示可选,可以有,也可以没有,如果不写 = {},等于号和方法主体,那么该方法会被隐式声明为抽象(abstract),包含他的类型也是也是一个抽象类型
1) 方法声明关键字为def (definition)
2) [参数名: 参数类型],... :表示函数的参数列表,可以没有。 如果有,多个参数使用逗号间隔
3) 方法中的语句:表示为了实现某一功能代码块
4) 方法可以有返回值,也可以没有
5) 返回值形式1: : 返回值类型 =
def getRes(n1: Int, n2: Int, oper: Char): Int = {
n1 + n2
}
6) 返回值形式2: = 表示返回值类型不确定,使用类型推导完成
def getRes(n1: Int, n2: Int, oper: Char):Int = { //方法声明处的返回值:Int
if (oper == '+') {
n1 + n2
} else if (oper == '-') {
n1 - n2
} else {
null //运行报错
}
}
注意:因为null是AnyRef的子类,但是null不是AnyVal的子类,这儿编译不会报错,但是运行会报typeError异常,如果非要返回null,则可以将方法返回值 :Int 去掉,直接使用 = 号,Scala会自动进行返回类型推断
7) 返回值形式3: 表示没有返回值,return 不生效
def getRes(n1: Int, n2: Int, oper: Char) {
return n1 + n2 //代码运行正常,但是return不生效
}
8) 如果没有return,默认以执行到最后一行的结果作为返回值
② 方法注意事项
1)方法的形参列表可以是多个, 如果方法没有形参,调用时可以不带()
2)形参列表和返回值列表的数据类型可以是值类型和引用类型
3)Scala中的方法可以根据方法体最后一行代码自行推断方法返回值类型。那么在这种情况下,return关键字可以省略
4)因为Scala可以自行推断,所以在省略return关键字的场合,返回值类型也可以省略
5)如果方法明确使用return关键字,那么方法返回就不能使用自行推断了,这时要明确写成 : 返回类型 = ,当然如果你什么都不写,即使有return 返回值为()
def getSum(n1: Int, n2: Int) = { // = 号不能省略,如果省略了,就表示没有返回值,res得到的就是()
n1 + n2
}
6)如果方法明确声明无返回值(声明Unit),那么方法体中即使使用return关键字也不会有返回值
7)如果明确方法无返回值或不确定返回值类型,那么返回值类型可以省略(或声明为Any)
8)Scala语法中任何的语法结构都可以嵌套其他语法结构(灵活),即:方法中可以再声明/定义方法,类中可以再声明类 ,方法中可以再声明/定义方法
object TestDef {
def main(args: Array[String]): Unit = {
//main函数中再声明/定义方法sayHello
def sayHello(name: String): String = {
def sayHello(name: String): String = {
name + " hello"
}
sayHello(name)
}
var r = sayHello("terry")
println("r=" + r) //r=terry hello
}
}
9)Scala方法的形参,在声明参数时,直接赋初始值(默认值),这时调用方法时,如果没有指定实参,则会使用默认值。如果指定了实参,则实参会覆盖默认值
object Test {
def main(args: Array[String]): Unit = {
println(sayOk())
println(sayOk("Tom")) //覆盖默认值
}
def sayOk(name : String = "jack"): String = {
return name + " ok! "
}
}
10)如果方法存在多个参数,每一个参数都可以设定默认值,那么这个时候,传递的参数到底是覆盖默认值,还是赋值给没有默认值的参数,就不确定了(默认按照声明顺序[从左到右])。在这种情况下,可以采用带名参数
/**
* @author huleikai
* @create 2019-05-17 11:56
*/
object TestDefArgs {
def main(args: Array[String]): Unit = {
mysqlCon() //不传参则使用默认值
mysqlCon("127.0.0.1", 8080) //按默认参数顺序对应覆盖
mysqlCon(pwd = "123456") //使用带名参数覆盖某个默认值
}
def mysqlCon(add: String = "localhost", port: Int = 3306,
user: String = "root", pwd: String = "root"): Unit = {
println("add=" + add)
println("port=" + port)
println("user=" + user)
println("pwd=" + pwd)
}
}
11)Scala 方法的形参默认是val的,因此不能在方法中进行修改
12)递归方法未执行之前是无法推断出来结果类型,在使用时必须有明确的返回值类型
13)Scala方法支持可变参数
def sum(args :Int*) : Int = {}
3.Scala 函数
函数与方法大致一样,但在scala中,函数的概念更为重要与广泛,并且更为灵活。
① 定义一个函数
类似方法的定义规则:
def abs (x: Double) = if (x > 0) x else -x
在函数不是递归函数的情况下,scala可以通过=后面的表达式推断出返回值类型。但是,一旦函数是递归的,那么你也需要显示指定返回值类型:
def res(n: Int): Int = if (n < 0) 1 else n * res(n-1)
② 匿名函数
Scala 中定义匿名函数的语法很简单,箭头左边是参数列表,右边是函数体。使用匿名函数后,我们的代码变得更简洁了。
下面的表达式就定义了一个接受一个Int类型输入参数的匿名函数:
val add = (x:Int,y:Int) => x+y
上述定义的匿名函数,其实是下面这种写法的简写:
def add = new Function1[Int,Int]{
def apply(x:Int):Int = x+1;
}
add 现在可作为一个函数,使用方式如下:
println(add(3, 4))
我们也可以不给匿名函数设置参数,如下所示:
val emptyFunc = () => { println("Hello Scala!") }
上面我们说过,如果一个方法无参数列表,则可以调用的时候直接写方法名即可,但是无参匿名函数调用时则必须带上()括号
println( emptyFunc() )
4.方法和函数的相互转化及使用
因为函数本身其实就是一个继承了Trait的对象,所以将函数当做方法的参数传参自然没什么问题,相当于java中的方法的自定义Student类的对象传参一样,所以函数既可以当做方法的参数传入,也可以当做函数的参数传入
而方法本身不能直接当做参数,但可以先转化为函数再进行传参,如果在一个方法或函数的参数中传入符合参数类型条件的方法,那么Scala编译器会默认将该方法转化为函数传入
当然方法也可以使用方法名+空格+_将方法转化为函数,如下图所示:
5.Scala 的异常Exception
① Scala 异常处理举例
try {
val num = 10 / 0
} catch {
case ex: ArithmeticException => println("捕获了除数为零的算数异常")
case ex: Exception => println("捕获了异常")
} finally {
//最终要执行的代码
println("scala finally...")
}
② Scala自定义异常类
在Scala中,可以创建自己的异常。它也称为自定义异常。通过扩展Exception类,同时声明自定义异常类。在自定义类中创建自己的异常消息。下面我们来看一个例子:
//声明一个异常类继承Exception
class InvalidAgeException(s: String) extends Exception(s) {}
class ExceptionExample {
@throws(classOf[InvalidAgeException])
def validate(age: Int) {
if (age < 18) {
throw new InvalidAgeException("Not eligible")
} else {
println("You are eligible")
}
}
}
object Demo {
def main(args: Array[String]) {
var e = new ExceptionExample()
try {
e.validate(5)
} catch {
case e: Exception => println("Exception Occured : " + e)
}
}
}
③ Scala异常处理总结
1)Scala的异常的工作机制和Java一样,但是Scala没有 checked(编译期) 异常,即Scala没有编译异常这个概念,异常都是在运行的时候捕获处理
2)用throw关键字,抛出一个异常对象。所有异常都是Throwable的子类型。throw表达式是有类型的,就是Nothing,因为Nothing是所有类型的子类型,所以throw表达式可以用在需要类型的地方
def main(args: Array[String]): Unit = {
val res = test()
println (res.toString)
}
def test(): Nothing = {
throw new Exception("出现异常")
}
3)在Scala里,借用了模式匹配的思想来做异常的匹配,因此,在catch的代码块中,是一系列case子句来匹配对应的异常。类似 java 的 switch case x: 代码块
4)异常捕捉的机制与其他语言中一样,如果有异常发生,catch子句是按次序捕捉的。因此,在catch子句中,越具体的异常越要靠前,越普遍的异常越靠后,如果把越普遍的异常写在前,把具体的异常写在后,在scala中也不会报错,但这样是非常不好的编程风格
5)Scala提供了throws关键字来声明异常。可以使用方法定义声明异常。 它向调用者函数提供了此方法可能引发此异常的信息。 它有助于调用函数处理并将该代码包含在try-catch块中,以避免程序异常终止。在scala中,可以使用throws注释来声明异常
def main(args: Array[String]): Unit = {
f11()
}
@throws(classOf[NumberFormatException]) //等同于NumberFormatException.class
def f11() = {"abc".toInt}
---------------------
Scala语言学习笔记——方法、函数及异常的更多相关文章
- Go语言学习笔记(7)——函数和方法
Go语言中同时有函数和方法! 函数: go程序必须要包含一个main函数.main函数不能有任何参数和返回值! 1. 定义方法示例: func max(num1, num2 int) int { // ...
- 【Go语言学习笔记】函数做参数和闭包
函数做参数 在Go语言中,函数也是一种数据类型,我们可以通过type来定义它,它的类型就是所有拥有相同的参数,相同的返回值的一种类型.类似于重写(同名覆盖). 回调函数:函数有一个参数是函数类型,这个 ...
- Go语言学习笔记(五) [函数]
日期:2014年7月29日 1.函数定义:func (p type) funcname(q int) (r,s int) {return 0,0 } func: 保留字,用于定义一个函数 ...
- Scala语言学习笔记(2)
表达式,值,变量,代码块,函数,方法 // 表达式 1 + 1 println(1 + 1) // 2 // 值(values)使用 val 关键字声明,带初值时类型可省略. val x = 1 + ...
- Scala语言学习笔记(4)
高阶函数 // 高阶函数 map val salaries = Seq(20000, 70000, 40000) val doubleSalary = (x: Int) => x * 2 val ...
- C语言学习笔记--字符串函数
字符串函数 需要包含头文件#include<stdio.h> strlen strcmp strcpy strchr strstr strcasestr
- Scala语言学习笔记(3)
类 // 定义并使用类 class User val user1 = new User // 主体构造器(primary constructor) class Point(var x: Int, va ...
- C语言学习笔记之函数指针与函数指针数组
指针函数:本质是一个函数: 是一个返回指针类型的函数int * sum(){ } 函数指针:本质是一个指针: 是一个指向函数的指针 int (*p)(int,int) = sum; p(5,6); i ...
- Go语言学习笔记七: 函数
Go语言学习笔记七: 函数 Go语言有函数还有方法,神奇不.这有点像python了. 函数定义 func function_name( [parameter list] ) [return_types ...
随机推荐
- linux -- 视频尺寸-cif、2cif、dcif、D1、HD1、4D1
1 CIF简介 CIF是常用的标准化图像格式(Common Intermediate Format).在H.323协议簇中,规定了视频采集设备的标准采集分辨率.CIF = 352×288像素 ...
- [poj1363]Rails_模拟_栈
Rails poj-1363 题目大意:判断一个序列是否是1~n的合法出栈序列. 注释:$1\le n\le 10^4$. 想法:开始想到一种想法. 对于一段序列来讲,显然从首元素开始的连续小于尾元素 ...
- 51nod——1432 独木桥
https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1432 基准时间限制:1 秒 空间限制:131072 KB 分值: 10 ...
- Android开发之PullToRefresh的Click点击事件的监听实现长按删除Item
本文为原创博客.出自http://blog.csdn.net/minimicall 到今天为止,搜芽的卖家版本号应该来说已经基本完毕.攻坚克难的一路过来.速度也控制的比較好. 项目过程进度 从任务分配 ...
- 菜鸟nginx源代码剖析 配置与部署篇(一) 手把手实现nginx "I love you"
菜鸟nginx源代码剖析 配置与部署篇(一) 手把手配置nginx "I love you" Author:Echo Chen(陈斌) Email:chenb19870707@gm ...
- Python图像处理库PIL中图像格式转换(一)
在数字图像处理中,针对不同的图像格式有其特定的处理算法. 所以,在做图像处理之前,我们须要考虑清楚自己要基于哪种格式的图像进行算法设计及事实上现.本文基于这个需求.使用python中的图像处理库PIL ...
- 【Java并发编程实战】—– AQS(四):CLH同步队列
在[Java并发编程实战]-–"J.U.C":CLH队列锁提过,AQS里面的CLH队列是CLH同步锁的一种变形. 其主要从双方面进行了改造:节点的结构与节点等待机制.在结构上引入了 ...
- mongoDB学习笔记——存取图片(C#)
作为一个NoSql数据库的代表,存取多媒体数据,应该是强项吧?那么,图片在mongoDB里是如何存取的呢?(其实,关系型数据库存取图片也一点问题没有,所以我看NoSql的强项不在于是否存储多媒体,而在 ...
- Android 6.0 中TimePicker显示为滚动样式的方法
在Android6.0中,TimePicker控件的默认样式为转盘的样式,就像这个样子: 如果想要显示为之前的滚动样式的话也很简单,只要在布局文件中设置TimePicker的timePickerMod ...
- WebSocket在Asp.Net中的例子
环境 以下代码环境要求:win8或win10, .net4.5+IIS8 部署到IIS8上面 转到 Windows程序和功能 -打开Windows功能里面 IIS选项启动4.5 和WebSocket支 ...