方法和函数的区别
两者在语义中的区别很小
在scala中:方法是类的一部分
函数是一个对象,可以赋值给一个变量
类中的就是方法,普通的就是函数
换句话说:在类中定义的函数就是方法
scala中的方法类似于java中的方法,是组成类的一部分
scala中的函数则是一个完整的对象,scala中函数其实就是继承了Trait的类的对象
scala中使用val语句定义函数,def语句定义方法
class Test{
def m(x:Int) = x + 3
val f(x : Int) => x + 3
}
方法的声明
def functionName([参数列表]):[return type]
如果不写等于号和方法主体,那么方法会隐式声明为抽象(abstract),包含它的类型也是抽象类型
方法定义
def functionName([参数列表]):[returntype] = {
function body
return [expr]
}
例:两数求和(有返回值)
object add{
def sumab(a:Int,b:Int):Int = {
var sum:Int = 0
sum = a + b
return sum
}
}
无返回值
object app{
def printhello():Unit={
println("Hello World!")
}
}
方法调用
标准格式
1)functionName(参数列表)
object Test {
def main(args: Array[String]) {
println("The Result:"+addInt(5,7));
}
def addInt( a:Int, b:Int ) : Int = {
var sum:Int = 0
sum = a + b
return sum
}
}
2)通过实例对象来调用
object Test {
class AddTest{
def addInt( a:Int, b:Int ) : Int = {
var sum:Int = 0
sum = a + b
return sum
}
}
def main(args: Array[String]) {
val add = new AddTest()
println("The Result:"+add.addInt(5,7));
}
}
函数调用
默认两种调用方式:(1)传值调用(call-by-value):先计算参数表达式的值,在应用到函数内部
(2)传名调用(call-by-name):将未计算的参数表达式直接应用到函数内部(使用 => 符号设置传名调用)
object Test{
def main(args:Array[String]){
delayed(time())
}
def time()={
println("Get time")
System.nanoTime
}
//注意有空格
def delayed(t: => Long)={
print("zai delayed zhong")
print("can shu :"+t)
t
}
}
指定函数参数名
传递参数时若参数名存在,改变顺序不会影响传递结果
object Test {
def main(args: Array[String]) {
printInt(b=5, a=7)
println() //结果相同
printInt(a=7,b=5)
}
def printInt( a:Int, b:Int ) = {
print("Value of a : " + a );
print("Value of b : " + b );
}
}
可变参数
Scala 允许你指明函数的最后一个参数可以是重复的,即我们不需要指定函数参数的个数,可以向函数传入可变长度参数列表。
Scala 通过在参数的类型之后放一个星号来设置可变参数(可重复的参数)。
object Test {
def main(args:Array[String])={
printString("zhangfei","liubei","guanyu")
}
def printString(a:String*)={
val i:Int = 0
for(a<-a){
println(a)
}
}
}
递归函数
通过设置条件不断调用函数
object aaa{
def main(args:Array[String]){
val a = leicheng(10)
println(a)
}
def leicheng(a:Int):Int={
if(a == 1)
1
else{
a*leicheng(a-1)//循环调用,直至条件不满足
}
}
}
偏应用函数
偏应用函数是一种表达式,不需要提供函数所需要的所有参数,只需要提供部分,或不提供所需参数。
import java.util.Date
object Test {
def main(args:Array[String]){
val date = new Date
/**
偏应用函数优化以上方法,绑定第一个 date 参数
第二个参数使用下划线(_)替换缺失的参数列表,并把这个新的函数值的索引的赋给变量。
**/
val sampleTime = sTime(date,_:String)
sampleTime("zhangfei")
Thread.sleep(1000)
sampleTime("guanyu")
Thread.sleep(1000)
sampleTime("liubei")
Thread.sleep(1000)
}
def sTime(date:Date,message:String){
println("muzijing"+"---"+date+"---"+message)
}
}
默认参数值
object Test {
def main(args:Array[String]){
println(sumab())
//结果为9
/**
传递参数时会覆盖默认值
println(sumab(2,8))
结果为10
**/
}
def sumab(a:Int=3,b:Int=6):Int={
val sum:Int = a + b
sum
}
}
匿名函数
Scala 中定义匿名函数的语法很简单,箭头左边是参数列表,右边是函数体
object Test {
def main(args:Array[String]){
var int1 = (a:Int) => a+1
var b = int1(2)
println(b)
}
/**
var int1 = (a:Int) => a+1
==========等同于============
def add = new Function(Int,Int){
def apply(x:Int):Int = x+1
}
**/
}
同理,可以设置多个参数或无参数
//多个参数
var int1 = (a:Int,b:Int) => a*b
var b = int1(2,3)
//无参数
var userDir = () => { System.getProperty("user.dir") }
println(userDir )
函数嵌套
我们在scala函数中定义函数时,定义在函数中的函数成为局部函数
object Test {
def main(args:Array[String]){
println(aaa(0))
println(aaa(1))
println(aaa(2))
println(aaa(3))
}
def aaa(i:Int):Int={
def bbb(i:Int,j:Int):Int={
if(i<=1)
j
else
bbb(i-1,j*i)
}
bbb(i,1)
}
}
高阶函数
高阶函数(Higher-Order Function)—操作其他函数的函数
Scala 中允许使用高阶函数, 高阶函数可以使用其他函数作为参数,或者使用函数作为输出结果。
object Test {
def main(args: Array[String]) {
println( apply( layout, 10) )
}
// 函数 f 和 值 v 作为参数,而函数 f 又调用了参数 v
def apply(f: Int => String, v: Int) = f(v)
def layout[A](x: A) = "[" + x.toString() + "]"
}
函数柯里化
柯里化(Currying)指的是将原来接受两个参数的函数变成新的接受一个参数的函数的过程。新的函数返回一个以原有第二个参数为参数的函数。
//首先我们定义一个函数:
def add(x:Int,y:Int)=x+y
//将x和y分成两部分add(x:Int)(y:Int)
def add = (x:Int)(y:Int) = x + y
/**演变过程
def add(x:Int)=(y:Int)=>x+y
接收一个x为参数,
返回一个匿名函数,
该匿名函数的定义是:
接收一个Int型参数y,函数体为x+y
------------
对这个方法进行调用
val result = add(1)
返回一个result,那result的值应该是一个匿名函数:(y:Int)=>1+y
继续调用result
val sum = result(2)
结果就是3
**/
object Test {
def main(args: Array[String]) {
val str1:String = "Hello, "
val str2:String = "Scala!"
println( "str1 + str2 = " + strcat(str1)(str2) )
}
def strcat(s1: String)(s2: String) = {
s1 + s2
}
}