scala函数使用--学习笔记
来源:互联网 发布:chart.js 使用xml 编辑:程序博客网 时间:2024/06/07 22:45
Scala里,当你调用函数,传入任何需要的参数,实际是把函数应用到参数上
1. 函数先单独在代码中定义,然后在其他代码中单独调用
// 第一种定义样式:
scala> def max(x:Int, y:Int):Int={
| if(x>y) x
| else y
}
max: (x: Int, y: Int)Int
// 第二种定义样式:如果函数体代码只有一行,则花括号可以省略;且函数返回类型可以由scala推断得出,则返回类型可以省略
scala> def max2(x:Int,y:Int)=if(x>y) x else y
max2: (x: Int, y: Int)Int
scala> max(3,5)
res0: Int = 5
scala> max2(5,3)
res1: Int = 5
// 第三种定义样式,函数不带返回值和参数:
scala> def greet()=println("Hello,world")
greet: ()Unit
scala> greet
Hello,world
scala> greet()
Hello,world
//第四种定义样式,函数不返回值(结果类型为Unit的函数才可以用此种定义样式),省略返回类型和等于号,保留花括号
scala> def greet3(){println("Hello")}
greet3: ()Unit
scala> greet3Hello
如果此种样式函数体的最后一句话返回的是有值的,那么函数会将值丢弃,并把返回类型转换为Unit。想要函数有返回值的话,千万不能省略等号
2. 函数作为参数,使用函数字面量
以下三种样式,arg为函数字面量的参数,println语句为字面量函数体
//第一种样式:使用函数字面量,参数类型可推断
args.foreach(arg=>println(arg))
//第二种样式:使用函数字面量,写明参数类型
args.foreach((arg:String)=>println(arg))
//第三种样式:使用函数字面量,函数体只有一行且只带一个参数
args.foreach(println)
综上,函数字面量的语法构成为:(x:Int, y:Int)=>x+y 参数列表+右箭头+函数体
函数的参数是 val 的,是不可变的,在函数体内给参数复制都会编译失败
如果没有发现任何显示的返回语句,Scala方法将返回方法中最后一次计算得到的值
3. 若方法只有一个参数,调用时可以省略点和括号。
val greetStrings = new Array[String](3)
for( i <- 0 to 2 ){
println(greeting(i))
}
to实际上是只带有一个Int参数的方法,代码 “0 to 2”可以转换成“(0).to(2)”,返回了可以让for表达式遍历的含有 0,1,2 的序列。如下:
scala> (0).to(2)
res8: scala.collection.immutable.Range.Inclusive = Range(0, 1, 2)
scala> 2 to 5
res33: scala.collection.immutable.Range.Inclusive = Range(2, 3, 4, 5)
从技术层面上说,Scala没有操作符重载,因为它根本没有传统意义上的操作符。取而代之的是,+-*/加减乘除这样的字符,可以用来做方法名。
1+2可以转换成(1).+(2)
scala> 1+2
res10: Int = 3
scala> 1.+(2)
res11: Int = 3
scala> (1).+(2)
res12: Int = 3
4. 无返回值的函数的结果类型是 Unit 的,unit value是存在且唯一存在类型为 Unit 的值,写成 ()
def processFile(filename: String, width: Int): Unit ={
//定义本地函数,外部无法访问本地函数,本地函数可以使用外层函数的输入参数
def processLine(line:String): Unit ={
if (line.length>width)
println(filename+": "+line)
}
val source=Source.fromFile(filename)
for(line <- source.getLines())
processLine(line)
//for 循环也可以用以下的 foreach 方法代替
source.getLines().foreach(processLine)
}6. 可以用字面量定义函数,并把它们作为值进行传递
increase: Int => Int = <function1>
scala> increase(10)
res26: Int = 11
scala> increase = (x:Int)=>{
| println("We are")
| println(" family")
| x+1
| }
increase: Int => Int = <function1>
scala> increase(10)
We are
family
res27: Int = 11
We are
family
We are
family
scala> List(1,2).foreach((x:Int)=>{ //在foreach里使用 函数字面量定义的函数 作为输入参数
| println(x+1)
| println("We are family")
| })
2
We are family
3
We are family
scala> List(1,2).filter(x=>x>1) //在filter过滤器里使用 函数字面量定义的函数 作为过滤条件的输入参数。且当可以推断出函数的参数类型时,省略类型和括号
res31: List[Int] = List(2)
res32: List[Int] = List(2)
f: (Int, Int) => Int = <function2>
scala> val f2=println(_)
<console>:14: error: missing parameter type for expanded function ((x$1) => println(x$1))
val f2=println(_)
^
sum: (a: Int, b: Int)Int
scala> val a=sum
<console>:15: error: missing argument list for method sum
Unapplied methods are only converted to functions when a function type is expected.
You can make this conversion explicit by writing `sum _` or `sum(_,_)` instead of `sum`.
val a=sum
^
scala> val a=sum _ //下划线代表sum函数定义时的参数 a和b。这条语句让编译器产生的类中有一个apply方法带了2个参数
a: (Int, Int) => Int = <function2>
scala> a(1,2) //这条语句执行时实际上调用的是 a.apply(1,2)
res33: Int = 3
res34: Int = 3
a2: Int => Int = <function1>
scala> a2(5)
res35: Int = 6
1
2
more: Int = 1
scala> val addMore= (x:Int)=>x+more //函数创建时绑定的是其外层变量的索引,而不是当时变量的值。more称作“自由变量”
addMore: Int => Int = <function1>
scala> addMore(2)
res37: Int = 3
scala> more=3
more: Int = 3
scala> addMore(2)
res38: Int = 5
sum: Int = 0
scala> List(1,2,3).foreach(sum += _) //自由变量在函数体内被改变
scala> sum
res42: Int = 6
| println("x="+x)
| (x+more).toString
| }
m1: (more: Int)Double => String
scala> val inc1=m1(1)
inc1: Double => String = <function1>
scala> val inc2=m1(10)
inc2: Double => String = <function1>
scala> inc1(10)
x=10.0
res7: String = 11.0
scala> inc2(20)
x=20.0
res1: String = 30.0
echo: (args: String*)Unit
scala> echo()
scala> echo("One")
One
scala> echo("One","Two")
One
Two
<console>:13: error: type mismatch;
found : Array[String]
required: String
echo(Array("A","B"))
^
scala> echo(Array("A","B"): _*) // :_* 告诉编译器把数组里的每个元素当做参数,而不是当做单一参数传给 echo
A
B
| if (x==0) throw new Exception("boom!")
| else boom(x-1)+1
| }
boom: (x: Int)Int
scala> boom(3)
java.lang.Exception: boom! //没有尾递归则增加了函数调用的开销
at .boom(<console>:12)
at .boom(<console>:13)
at .boom(<console>:13)
at .boom(<console>:13)
... 32 elided
| if (x==0) throw new Exception("boom2!")
| else boom2(x-1)
| }
boom2: (x: Int)Int
scala> boom2(3)
java.lang.Exception: boom2!
at .boom2(<console>:14)
... 32 elided
- scala函数使用--学习笔记
- Scala学习笔记17【Scala偏函数】
- Scala 学习笔记(六)------Scala 函数嵌套
- scala学习笔记:理解函数
- scala学习笔记之函数
- scala学习笔记 之 函数
- Scala学习笔记之Scala函数及函数式编程
- Scala学习笔记03【学习识别Scala函数式风格】
- scala学习笔记三----scala函数式编程风格学习
- Scala学习笔记07【For、Scala函数进阶】
- scala中的函数、变量、集合、对象---scala学习笔记(1)
- Scala学习笔记(三)scala的函数式编程
- [Scala]Scala学习笔记八 高阶函数
- scala学习笔记(三)Scala函数式编程
- Scala学习笔记22【继续学习Scala List的使用】
- scala学习笔记:高阶函数
- Scala学习笔记4--函数值
- scala学习笔记:函数与方法
- redis 启动时指定配置文件
- 关于中断的模式 RXNE TC TXE 等等的含义(看着就乱)
- 剑指offer-面试题18-树的子结构
- CSS第一课
- 普通大学生互联网逆袭风雨路
- scala函数使用--学习笔记
- Android实现推送方式解决方案
- hugepage总结
- MyEclipse+Maven创建SSM(springMVC+spring+mybatis)项目
- Bom编程
- Spark -4:maven编译spark 源码
- 二叉树的镜像
- 一道数学题~~
- Java 中的访问修饰符