这篇文章主要介绍“scala函数怎么定义和调用”,在日常操作中,相信很多人在scala函数怎么定义和调用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”scala函数怎么定义和调用”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
一、函数的定义和调用 def
scala定义函数时,需要用def做修饰,然后指定函数名,参数和函数体,在参数列表和函数体中加上 = 号,如下:
scala> :paste// Entering paste mode (ctrl-D to finish)def say(name : String,age : Int)={ println("my name is"+name+",my age is"+age)}// Exiting paste mode, now interpreting.say: (name: String, age: Int)Unitscala> say("xiaoming",18)my name isxiaoming,my age is18
可以看出,参数用冒号指定其类型,不同参数逗号分隔开,使用时直接调用函数名,指定参数即可
scala的函数也能拥有返回值,跟java不同,scala并不适用return,而是一条语句的最后一个值就是返回值,说起来拗口,直接上代码:
scala> :paste// Entering paste mode (ctrl-D to finish)def sayage(age : Int)={ if(age >= 18){ println("I am a adult "+ age) age }else{ println("I am a children "+ age) age }}// Exiting paste mode, now interpreting.sayage: (age: Int)Intscala> sayage(22)I am a adult 22res4: Int = 22
在上面的代码我们可以看出,if分支打印输出之后都有一个单独一行的age,这就是返回值,scala对于函数的返回值基本都可以自动推断出来,但在这里还是额外说一下,scala是可以自己指定返回值的,如下:
scala> :paste// Entering paste mode (ctrl-D to finish)def sayAge(age : Int):Int ={ if(age >= 18){ println("I am a adult "+ age) age }else{ println("I am a children "+ age) age }}// Exiting paste mode, now interpreting.
看出区别了吗,对,就在def sayAge(age : Int):Int
这里,参数列表后使用冒号加类型的方式指定函数返回值
如果函数体不是多行,也可以简化去掉大括号,如下:
scala> def sayHello(name : String) = println("my name is " + name)sayHello: (name: String)Unitscala> sayHello("xiaoming")my name is xiaoming
二、默认参数和带名参数
有时候我们希望不给参数具体值,而是使用参数默认值,scala可以做到这一点
scala> :paste// Entering paste mode (ctrl-D to finish)def sayHello(name:String,age:Int = 18)=print("name:"+name+" age:"+age)// Exiting paste mode, now interpreting.sayHello: (name: String, age: Int)Unitscala> sayHello("DaXin")name:DaXin age:18
如上图代码所示,name没有默认值,必须要手动传值,age给出默认值18,使用时就能读取到
scala还支持以不按照函数定义的参数顺序来传递参数,也就是带名参数
scala> sayHello(age = 50,name = "Dad")name:Dad age:50
像这样把参数颠倒也是可以正常使用的
三、变长参数
有时候我们需要函数参数个数可变,这时候可以使用变长参数
scala> :paste// Entering paste mode (ctrl-D to finish)def sum(numbers : Int*) = { var result = 0; for(number <- numbers){ result = result+number } result}// Exiting paste mode, now interpreting.sum: (numbers: Int*)Intscala> sum(1,3,5,6)res2: Int = 15
注意到参数类型Int后面的*号了吗?这就是变长参数的语法,代表调用时可以传入多个Int类型
还有一种情况,我们不想写(1,3,5,6)
这样的参数,而是前面说过的1 to 4
这样的参数,可以吗?事实上不行,因为1 to 4
本质上是RichInt类型, 而变长参数需要的是多个单Int类型,这时候就需要新的解决办法:
//:_*告诉编译器你希望将某个参数当作参数序列处理scala> sum(1 to 4:_*)res3: Int = 10
四、过程
过程其实是个非常简单的概念,如果一个scala函数的函数名和函数体之间没有使用等号连接,只是用花括号包住了函数体,那他的返回值类型就是Unit,总结一下:过程就是返回值为Unit,也就是不需要返回值的函数
scala> def say(name: String) { print("Hello, " + name)}say: (name: String)Unitscala> say("daXin")Hello, daXin
五、lazy和异常机制
lazy:把一个变量声明为lazy,那么这个变量只有在真正使用的时候才会被加载,适用于耗时操作,或者只有触发某些特殊情况才会调用的变量
//定义一个长度为5的数组scala> var slist = 1 to 5slist: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3, 4, 5)//已经越界,但是lazy变量不报错scala> lazy val e = slist(5)e: Int = <lazy>//在使用的时候才会报错scala> ejava.lang.IndexOutOfBoundsException: 5 at scala.collection.immutable.Range.apply$mcII$sp(Range.scala:151) at scala.collection.immutable.Range.apply(Range.scala:149) at .e$lzycompute(<console>:15) at .e(<console>:15) ... 32 elided //而且lazy只能使用val定义,var会报错scala> lazy var num = slist(2)<console>:1: error: lazy not allowed here. Only vals can be lazylazy var num = slist(2)
scala的异常和java很像,我们来看看
//引入io包,下面会用到IO异常scala> import java.io._import java.io._scala> :paste// Entering paste mode (ctrl-D to finish)try{//抛出Illegal异常 throw new IllegalArgumentException("error")}catch{//scala的catch没有(),花括号内是case来判断不同异常,上面抛出Illegal异常,所以IO异常会跳过,在下面被捕获到//顺便一提抛出的异常如果没有相应的case能捕获,就会报错 case e1:IOException =>print("IO fail") case e2:IllegalArgumentException =>print("Illegal fail")}// Exiting paste mode, now interpreting.Illegal fail
到此,关于“scala函数怎么定义和调用”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。
原文链接:https://my.oschina.net/u/3969474/blog/4402823