- Scala 有方法与函数,二者在语义上的区别很小。Scala 方法是类的一部分,而函数是一个对象可以赋值给一个变量。换句话来说在类中定义的函数即是方法。
- Scala 中的方法跟 Java 的类似,方法是组成类的一部分。
- Scala 中的函数则是一个完整的对象,Scala 中的函数其实就是继承了 Trait 的类的对象。
- Scala 中使用 val 语句可以定义函数,def 语句定义方法。
一、基础语法
def method(参数列表)[:返回类型] = {方法体}
val func[:返回类型] = (参数列表)=> {方法体}
(参数列表)=> (方法体)
def cal1(inCal: (Int, Int) => Int, x: Int, y: Int) = inCal(x, y)
def cal2(inCal: (Int, Int) => Int)(x: Int, y: Int) = inCal(x, y)
def cal3(inCal: (Int, Int) => Int) = inCal
println(cal1(_ + _, 2, 5))
println(cal2(_ + _)(2, 5))
println(cal3(_ + _)(2, 5))
二、入参规则
- 直接入参:3个以内(x:A,y:B,z:C)
- 封装入参:3个以上
- 动态参数
- 元组、自定义类
三、传名调用
object Call_by_name {
var m =10
def count:Int={
m+=1
m
}
def printByName(x: =>Int):Unit={
for (elem <- 1 to 3) {
println(x)
}
}
def printByValue(x:Int):Unit={
for (elem <- 1 to 3) {
println(x)
}
}
def main(args: Array[String]): Unit = {
printByValue(count)`在这里插入代码片`
printByName(count)
}
}
四、指定参数名
object Appoint{
def appoint(a:Int,b:Int)={
a*a+ b/b
}
def main(args: Array[String]): Unit = {
println(appoint(2, 3))
println(appoint(3, 2))
println(appoint(a=3, b=2))
println(appoint(b=2, a=3))
}
}
五、动态参数
object strings{
def main(args: Array[String]): Unit = {
strings("a","b","d")
}
def strings(ss:String*):Unit={
for (elem <- ss) {
println(elem)
}
}
}
六、递归函数
object res{
def main(args: Array[String]): Unit = {
println(factorial(10))
}
def factorial(n:Int):Int={
if (n<=1){
1
}else{
n*factorial(n-1)
}
}
}
七、内嵌函数
object triangle {
def triangle(rows: Int): Unit = {
def space(row: Int): Unit = {
for (elem <- 1 to rows - row) {
print(" ")
}
}
def star(row: Int): Unit = {
for (elem <- 1 to 2 * row - 1) {
print("*")
}
println()
}
for (elem <- 1 to rows) {
space(elem)
star(elem)
}
}
def main(args: Array[String]): Unit = {
triangle(8)
}
}
八、高阶函数
- 高阶函数:以函数作为参数传递
object higherFunc{
def main(args: Array[String]): Unit = {
println(a(l, 20))//传入函数l作为a的参数1,20作为a的参数2
}
//a() 函数使用了另外一个函数 f 和 值 v 作为参数,而函数 f 又调用了参数 v
def a(f:Int=>String,v:Int)={
f(v)
}
def l[T](x:T):String={
"--"+x.toString+"--"
}
}
object higherFunc2{
def test(x:Int) = println(x)//基础函数:传值(或传函数的调用结果),返回值
def add(x:Int*)=x.reduce(_+_)
def test2(x:(Int,Int)=>Int,y:Int*)={
var sum = 0
for (elem <- y) {
sum = x(sum,elem)
}
sum
}
def main(args: Array[String]): Unit = {
test(add(1,2,3,4))
}
println(test2(_-_,1,2,3,4))
}
九、匿名函数
object anonymous1 {
def main(args: Array[String]): Unit = {
var inc = (x: Int) => x + 1
var a = inc(7)*2
println(a)
println(add(7) * 2)
}
def add(x:Int)={
x+1
}
}
十、库里化
- 以函数作为返回类型
- val func:(x : A ) => ? = (…) => {…}
- def method(x : A ) : ( y : A , … ) => ? = { … }
- 案例1:
object curry{
def main(args: Array[String]): Unit = {
println(add1(2, 3))
println(add2(2))
println(add2(2)(3))
println(add3(2)(3))
}
def add1(x:Int,y:Int):Int={
x+y
}
def add2(x:Int):Int=>Int={
y:Int=>x+y
}
def add3(x:Int)(y:Int):Int={
x+y
}
}
- 案例2:
object curry2{
//返回值一个函数“(Int,Int)=>Int”,调用时就会有两个参数
def func():(Int,Int)=>Int={
(x:Int,y:Int)=>x+y
}
//func()是一个函数名称,第二个()是参数
//func()
def func2(t:Char):(Int,Int)=>Int={
(x:Int,y:Int)=> t match {
case t if (t=='+')=>x+y
case t if (t=='*')=>x*y
case t if (t=='-')=>x-y
case t if (t=='/')=>x/y
}
}
def main(args: Array[String]): Unit = {
println(func()(2, 3))
println(func2('*')(2, 6))
println(func2('/')(2, 6))
println(func2('+')(2, 6))
println(func2('-')(2, 6))
}
}
十一、隐式参数
object yinshicanshu{
def printTriangle(rows:Int)(implicit up:Boolean=true)={
def printSpace(row:Int)={
for (elem <- 1 to (if(up) rows-row else row-1)) {
print(" ")
}
}
def printStar(row:Int)={
// for (elem <- 1 to (if(up) 2*row-1 else 2*rows+1-2*row)) {
for (elem <- 1 to (if(up) (row<<1)-1 else ((rows-row)<<1) -1)) {
print("*")
}
println()
}
for (elem <- 1 to rows) {
printSpace(elem)
printStar(elem)
}
}
def main(args: Array[String]): Unit = {
implicit val up = false
printTriangle(7)(false)
}
}
十二、隐式函数
object yinshiFunc{
case class Student(name:String)
object Student{
//隐式函数,放在被转化函数的伴生对象里
implicit def toPlayer(stu:Student)={
new Player(stu.name)
}
implicit def toSinger(stu:Student)={
new Singer(stu.name)
}
def show(implicit age:Int)=println(s"my name is $age")
}
class Player(name:String){
def play()=println(s"this is $name,I can play football")
}
class Singer(name:String){
def sing()=println(s"this is $name,I can sing a song")
}
def main(args: Array[String]): Unit = {
val stu:Student = new Student("henry")
stu.play()//student类里没有play方法,没找到,就去找隐式函数的伴生对象,如果没有
stu.sing()//student类里没有sing方法,没找到,就去找隐式函数的伴生对象,如果没有
implicit val age:Int=18
import logic.yinshiFunc.Student._
show
}
}
十三、偏函数
- 只处理、匹配一部分的内容
object pf{
def main(args: Array[String]): Unit = {
val list:List[Any] = List(1,2,3,"four")
list.collect({
case x: Int => x * 5
}).foreach(x=>println(x))
}
}
- 自定义偏函数
- 实现接口的isDefinedA和apply方法
object pf2{
def main(args: Array[String]): Unit = {
val pf = new PartialFunction[Any, Int] {
override def isDefinedAt(x: Any): Boolean = if (x.isInstanceOf[Int]) true else false
//能转就是true,不能转就是false
override def apply(v1: Any): Int = v1.asInstanceOf[Int] * 5
}
val list:List[Any] = List(1,2,3,"four")
println("-----偏函数-----------")
list.collect(pf).foreach(x=>print(s"$x "));println()
println("-----自定义偏函数-----")
list.collect({
case x: Int => x * 5
}).foreach(x=>print(s"$x "))
}
}
object pf3{
val pt1 = new PartialFunction[Int,Option[(String,Int)]] {
override def isDefinedAt(x: Int): Boolean = x%3==0||x%7==0
override def apply(v1: Int): Option[(String, Int)] ={
if (v1%3==0)
Some("three",v1)
else if(v1%7==0)
Some("seven",v1)
else
None
}
}
var pt2:PartialFunction[Int,Option[(String,Int)]]=(v:Int)=>v match {
case i if (i%3==0) =>Some(("three",i))
case i if (i%7==0) =>Some(("seven",i))
}
def main(args: Array[String]): Unit = {
println("--------第一种自定义创建方式--------")
Array.range(1,20).collect(pt1).foreach(x=>print(s"$x "));println()
println("--------第二种自定义创建方式--------")
Array.range(1,20).collect(pt1).foreach(x=>print(s"$x "))
}
}