scala函数

一.函数

函数声明

def functionName ([list of parameters]) : [return type]

1.定义无输入的函数

  示例:

def hi="hi"
scala>hi

def hi():String="hi"
scala>hi() 
scala>hi

2.定义函数

def functionName ([list of parameters]) : [return type] = {
   function body
   return [expr]
}

  示例:

//最后一行是函数的返回值
def multiplier(x:Int,y:Int):Int={x*y}
def safeTrim(s:String):String={
  if (s==null) return null
  s.trim()
}

 3.过程

     过程是没有返回值的函数。以一个语句(如println()调用)结尾的函数也是一个过程。

     返回类型为Unit 表示没有值。

   示例:

def log(d:Double)=println(f"Got value $d%.2f")

def log(d:Double):Unit=println(f"Got value $d%.2f")

 4.用表达式块调用函数

    使用一个参数调用函数时,可以利用一个大括号包围表达式发送参数,而不是用小括号包围值。

  示例:

def formatEuro(amt:Double)=f"$amt%.2f"

scala>formatEuro{val rate;0.2*rate+0.3}

 5.递归函数

   递归函数就是调用函数自身的函数,需要注意避免陷入无限循环。

  示例:

def power(x:Int,n:Int):Long={
   if(n>=1) x*power(x,n-1)
   else 1
}

 6.嵌套函数

   可以在函数中定义另一个内部函数,这个内部函数只能在该函数中使用。

  示例:

def max(a:Int,b:Int,c:Int)={
   def max(x:Int,y:Int)=if(x>y) x else y
   max(a,max(b,c))
}

 7.用命名参数调用函数

   在Scala中,可以按名调用参数,这样就不一定要按顺序指定参数。

  示例:

def greet(orefix:String,name:String)=s"$prefix $name"
val greeting=greet(name="Brown",prefix="Mr")

 8.为函数参数指定默认值

  示例:

def greet(name:String,orefix:String="")=s"$prefix $name"
val greeting=greet("Brown")

 9.Vararg参数

    要标志一个参数匹配一个或多个输入实参,在函数定义中需要该参数类型后面增加一个星号(*)

  示例:

def sum(items:Int*):Int={
   var total=0
   for(i<-items) total+=i
   total
}
scala>sum()  
res1:Int =0
scala>sum(10,20,30)
res2:Int=60

 10.参数组

    把参数表分解为参数组,每个参数组分别用小括号分隔。

  示例:

def max(x:Int)(y:Int)=if(x>y) x else y
val larger=max(20)(19)

 11.类型参数

    类型参数指示了值参数或返回值使用类型,函数参数或返回值的类型不再固定。可以由函数调用者设置。

  示例:

def identity[A](a:A):A=a

val s:String=identity[String]("hello")
val d:Double=identity[Double](2.345)

//类型推导:Scala编译器可以推导出类型参数的类型,以及将赋为返回值的值的类型。
val s=identity("hello")
val d=identity(2.345)

 二.首类函数

  “首类”表示函数不仅能得到声明和调用,还可以作为一个数据类型用在这个语言的任何地方。

1.函数类型

  ([<type>,...})=><type>  , 有单个参数的函数类型可以省略小括号.

  示例:

def double(x:Int):Int=x*2
val myDouble:(Int)=>Int=double
myDouble(5)

def logStart()="hello"
val start:()=>String=logStart
start()
 2.用通配符为函数赋值

  示例:

def double(x:Int):Int=x*2
val myDouble=double_
myDouble(20)
 3.高阶函数

   包含一个函数类型的值作为输入参数或返回值的函数

  示例:

//定义带函数类型的值作为参数的函数
def safeStringOp(s:String,f:String=>String)={
    if(s!=null) f(s) else s
}
def reverser(s:String)=s.reverse
//调用函数
safeStringOp("Ready",reverser)
  4.函数字面量

  示例:

val doubler=(x:Int)=>x*2
val doubled=doubler(20)

val greeter=(name:String)=>s"Hello,$name"
val hi=greeter("World")

//3中例子可写成
safeStringOp("Ready",(s:String)=>s.reverse)
 5.占位符语法

   占位符语法是函数字面量的一种缩写形式,将命名参数替换为通配符(_)。

  示例:

val doubler:Int=>Int=_*2

//3中例子可写成
safeStringOp("Ready",_.reverse)

def combination(x:Int,y:Int,f:(Int,Int)=>Int)=f(x,y)
combination(23,12,_*_)
res:Int=276

def tripleOp[A,B](a:A,b:A,c:A,f:(A,A,A)=>B)=f(a,b,c)
tripleOp[Int,Double](23,92,14,1.0*_/_/_)
 6.部分应用函数
   想重用一个函数,而且希望保留一些参数不想再次输入实,可以部分应用函数。
  示例:
def factorOf(x:Int,y:Int)=y%x==0
//部分应用
val multipleOf=factorOf(3,_:Int)
val y=multipleOf(78)

val isEven=factorOf(2)_
val z=isEven(32)
 7.传名参数    在函数中使用一个传名参数时,它会计算为一个值。如果向这个函数传入一个值,不会有任何作用,不过,如果向它传入一个函数,那么每次使用时都会调用这个函数。
  示例:
def doubles(x:=>Int)={
   println("Now doubling"+x)
   x*2
}
doubles(5)
运行结果:
Now doubling 5
res:Int=10

def f(i:Int)={println(s"Hello from f($i)");i}
double(f(8))
运行结果:
Hello from f(8)
Now Double 8
Hello from f(8)
res:Int=16
注:参考《Scala 学习手册》

猜你喜欢

转载自985359995.iteye.com/blog/2361180