05定义方法
本文最后更新于 2021-08-05 11:42:59
定义方法
- 如果函数签名和函数体之间的 =省略,这个函数返回Unit
- 函数调用的的时候,如果参数个数为0,则调用时括号可以省略
- 如果函数声明的时候,不需要传递参数,在定义时可以不加括号,调用的时候也不能加括号
- 函数的参数默认值都是 val ,所以不能更改参数值,若要更改,只能重新定义一个局部变量
- 函数声明的时候,参数可以带默认值
- 默认返回最后一行的值,scala会根据最后一行代码进行推导
- 有return 不能推导
- 返回值类型和推导类型不一致的时候不要推导
- 递归调用的时候不能推导
- scala默认是按照位置传参,也可以按照命名传参
object FunctionDemo1 {
def main(args: Array[String]): Unit = {
println(add(1, 2))
//没有参数传递 可以不加括号
my_print
my_print2
//通过命名传参
println(add(val1 = 1, val2 = 2))
}
def add(val1:Int,val2:Int):Int={
val1+val2
}
//自动推导返回值
def add2(val1:Int,val2:Int)={
val1+val2
}
def my_print(): Unit ={
println("1111")
}
//没有参数传递 可以不加括号,调用方法时就不能带括号
def my_print2: Unit ={
println("222")
}
def default_value(val1:Int=1,val2:Int=2)= val1+val2
}- 函数可以定义在任何位置,定义在函数的内部,外部不能调用
- 可以将内部的函数作为返回值,外部即可调用
- 可以将函数作为一个参数,传递给另外一个函数
- 函数可以作为值传递,方法不行
- def定义的严格意义上来说 都是方法
- 在有上下文环境下,比如明确指定了 接收为一个函数,方法可以自动转换为函数
object FunctionDemo2 {
def main(args: Array[String]): Unit = {
fun1
//返回函数并调用
val fun22 = fun2()
fun22()
//将函数整体做为参数
func3(func33 _)
//priv.king.function.FunctionDemo2$$$Lambda$6/2101440631@7dc36524
//直接定义函数
//函数不能声明返回值类型,只能靠推导 在参数列表后面不能指定返回值
//可以通过 _ 把方法转换成函数
//如果接收类型指定函数类型,后面可以不加 _ 会自动转换成函数
val f:Int=>Int=(a:Int)=>{a*a}
}
//函数可以定义在任何位置
//在函数内部定义函数
def fun1()={
fun11
def fun11()={
println("111")
}
}
//将函数作为返回值
def fun2()={
def fun22()={
println("22")
}
//将fun22(方法)转换为函数
fun22 _
}
def func3(x:(Int,Int)=>Unit)={
x(1,2)
println(x)
}
def func33(val1:Int,val2:Int)={
println("333"+val1+val2)
}
}匿名函数
object FunctionDemo3 {
def main(args: Array[String]): Unit = {
//使用lambda表达式 匿名函数
fun1(()=>{
println("1111")
})
func2((a:Int,b:Int)=>{a+b})
//已经指定必须为Int 所以可以省略
func2((a,b)=>a+b)
//参数只使用一次 可以使用 _ 代替,
//第一个 _ 表示第一个参数,第二个 _ 表示第二个参数 .....
func2(_ + _)
}
def fun1(f:()=>Unit): Unit ={
f()
}
def func2(f:(Int,Int)=>Int)={
println(f(1,2))
}
}
模拟foreach reduce map filter
object FunctionDemo4 {
def main(args: Array[String]): Unit = {
val arr1 = Array(10, 20, 30, 40, 50)
foreach(arr1, param => println(param))
foreach(arr1, println)
val arr2 = filter(arr1, _ % 2 == 0)
foreach(arr2, x=>print(s"$x\t"))
println()
val arr3 = map(arr1,x=>x*x)
foreach(arr3, x=>print(s"$x\t"))
println()
var reduce_res = reduce(arr1,_+_)
println(reduce_res)
}
def foreach(arr: Array[Int], op: Int => Unit) = {
for (elem <- arr) {
op(elem)
}
}
def filter(arr: Array[Int], condition: Int => Boolean): Array[Int] = {
for (i <- arr if condition(i)) yield {
i
}
}
def map(arr:Array[Int],op:Int=>Int):Array[Int]={
for(elem<-arr) yield op(elem)
}
def reduce(arr:Array[Int],op:(Int,Int)=>Int): Int ={
var param1 = arr(0);
for(i<- 1 until arr.length-1){
param1=op(param1,arr(i))
}
param1
}
}闭包
object FunctionDemo5 {
def main(args: Array[String]): Unit = {
val f = foo()
val r = f(10)
println(r) //20
val f1 = foo2()
println(f1()) //11
println(f1()) //12
val f2 = foo2()
println(f2()) //11
}
def foo() = {
//a相当于外部变量
var a = 10
b: Int => a + b
}
def foo2() = {
var a = 10
()=>{a+=1;a}
}
}
/*
闭包:
一个函数访问了外部的局部变量,则这个函数和它访问的局部变量称为闭包
闭包会阻值外部局部变量的销毁
*/class Outer{
private int ccc;
public void fun1(){
int a=1;
final int b = 2;
class Innor{
public void fun2(){
// System.out.println(a); error
System.out.println(b);
System.out.println(ccc);
}
}
//为什么在内部类中传递的参数(局部变量)必须是final
//不是final就是因为局部变量保存在栈中,栈弹出,变量就没有了
//声明为final就是常量
//主要还是看变量会不会出现生命周期不一致问题
//导致原因还是java没有闭包
new Thread(()->{
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//如果不是final,是一个局部变量
//这里方法内的局部变量就不存在了
Innor innor = new Innor();
innor.fun2();
}).start();
}
}
class Outer2{
final int b =11;
class Innor2{
final int b=1;
public void fun(){
//就近原则 访问自己的b
System.out.println(b);
//访问外部类的b
System.out.println(Outer2.this.b);
}
}
}05定义方法
https://jiajun.xyz/2020/11/02/scala/05定义方法/