函数和方法
scala
复制代码
package com.zishi.scala.a02.okk05
object Test01_FunctionAndMethod {
/**
* public void main(final String[] args) {
* sayHi$1("alice"); -- 这里调用的就是:sayHi$1
* this.sayHi("bob");
* String result = this.sayHello("cary");
* .MODULE$.println(result);
* }
*
* @param args
*/
def main(args: Array[String]): Unit = {
/**
* 定义函数
* 该函数不能重载
*
* 编译之后的字节码为:
* private static final sayHi$1(name: String): Unit = {
* MODULE$.println((new StringBuilder(4)).append("hi, ").append(name).toString)
* }
* 增加了修饰符:private static final
* 方法名被修改了:sayHi$1
*
* @param name
*/
def sayHi(name: String): Unit = {
println("hi, " + name)
}
// 不能重载 sayHi is already defined in the scope
/*def sayHi(i: Int): Unit = {
println("hi, " + i)
}*/
// 调用函数,不加任何的操作,默认调用函数
// 如果没有函数,则调用方法
sayHi("alice") // 这里调用的是函数
// 调用对象方法
Test01_FunctionAndMethod.sayHi("bob")
// 获取方法返回值
val result = Test01_FunctionAndMethod.sayHello("cary")
println(result)
}
// 定义对象的方法
def sayHi(name: String): Unit = {
println("Hi, " + name)
}
def sayHello(name: String): String = {
println("Hello, " + name)
return "Hello"
}
}
函数的定义
scala
复制代码
package com.zishi.scala.a02.okk05
object Test02_FunctionDefine01 {
def main(args: Array[String]): Unit = {
// (1)函数1:无参,无返回值
def f1(): Unit = {
println("1. 无参,无返回值")
}
f1()
println(f1())
println("=========================")
// (2)函数2:无参,有返回值
def f2(): Int = {
println("2. 无参,有返回值")
return 12
}
println(f2())
println("=========================")
// (3)函数3:有参,无返回值
def f3(name: String): Unit = {
println("3:有参,无返回值 " + name)
}
println(f3("alice"))
println("=========================")
// (4)函数4:有参,有返回值
def f4(name: String): String = {
println("4:有参,有返回值 " + name)
return "hi, " + name
}
println(f4("alice"))
println("=========================")
// (5)函数5:多参,无返回值
def f5(name1: String, name2: String): Unit = {
println("5:多参,无返回值")
println(s"${name1}和${name2}都是我的好朋友")
}
f5("alice", "bob")
println("=========================")
// (6)函数6:多参,有返回值
def f6(a: Int, b: Int): Int = {
println("6:多参,有返回值")
return a + b
}
println(f6(12, 37))
}
}
函数的可变参数
scala
复制代码
package com.zishi.scala.a02.okk05
object Test03_FunctionParameter {
def main(args: Array[String]): Unit = {
// (1)可变参数
def f1(str: String*): Unit = {
println(str)
}
f1("alice") // ArraySeq(alice)
f1("aaa", "bbb", "ccc") // ArraySeq(aaa, bbb, ccc)
// (2)如果参数列表中存在多个参数,那么可变参数一般放置在最后
def f2(str1: String, str2: String*): Unit = {
println("str1: " + str1 + ",str2: " + str2)
}
// 可变参数不确定,底层实现的方式也不一样
f2("alice") // str1: alice,str2: List()
f2("aaa", "bbb", "ccc") // str1: aaa,str2: ArraySeq(bbb, ccc)
// (3)参数默认值,一般将有默认值的参数放置在参数列表的后面
def f3(name: String = "eeeee"): Unit = {
println("My school is " + name)
}
f3("school")
f3()
// (4)带名参数
def f4(name: String = "eeeee", age: Int): Unit = {
println(s"${age}岁的${name}在smmmca学习")
}
f4("alice", 20)
f4(age = 23, name = "bob")
f4(age = 21)
}
}
函数的至简原则
scala
复制代码
package com.zishi.scala.a02.okk05
/**
* 函数至简原则
*/
object Test04_Simplify {
def main(args: Array[String]): Unit = {
def f0(name: String): String = {
return name
}
println(f0("erfearfere"))
println("==========================")
//(1)return可以省略,Scala会使用函数体的最后一行代码作为返回值
def f1(name: String): String = {
name
}
println(f1("erfearfere"))
println("==========================")
//(2)如果函数体只有一行代码,可以省略花括号
def f2(name: String): String = name
println(f2("erfearfere"))
println("==========================")
//(3)返回值类型如果能够推断出来,那么可以省略(:和返回值类型一起省略)
def f3(name: String) = name
println(f3("erfearfere"))
println("==========================")
// (4)如果有return,则不能省略返回值类型,必须指定
// def f4(name: String) = {
// return name
// }
//
// println(f4("erfearfere"))
println("==========================")
//(5)如果函数明确声明unit,那么即使函数体中使用return关键字也不起作用
def f5(name: String): Unit = {
return name
}
println(f5("f5 erfearfere"))
println("==========================")
/**
*(6)Scala如果期望是无返回值类型,可以省略等号
* =号省略的前提是 没有返回值
* @param name
*/
def f6(name: String) {
println(name)
}
println(f6("f6 erfearfere"))
println("==========================")
//(7)如果函数无参,但是声明了参数列表,那么调用时,小括号,可加可不加
def f7(): Unit = {
println("f7")
}
f7()
f7
println("==========================")
//(8)如果函数没有参数列表,那么小括号可以省略,调用时小括号必须省略
def f8: Unit = {
println("f8 f8")
}
/**
* 省略参数列表的小括号
* 省略返回值类型
* 省略方法体的花括号
*/
def f82 = println("f8 f8")
f82
//f8()
f8
println("==========================")
//(9)如果不关心名称,只关心逻辑处理,那么函数名(def)可以省略
def f9(name: String): Unit = {
println(name)
}
// 匿名函数,lambda表达式,无参函数
() => {
println("Hello lambda")
}
// 匿名函数,lambda 表达式,这里是有参函数
(name: String) => {
println(s"aaa ${name}", name)
}
println("-------------------")
}
}
函数也是对象
scala
复制代码
package com.zishi.scala.a02.okk05
/**
* 函数至简原则
*/
object Test04_Simplify02 {
def main(args: Array[String]): Unit = {
/**
* Scala是面向对象的语言,万物皆对象,
* 所以函数也是对象
*
* 既然函数是对象,
* 1. 那么函数这个对象应该有类型,
* 2. 并且可以赋值给其他人使用
*/
def test() = {
println("111")
}
// 调用了test函数,可以省略小括号
test
//打印函数返回结果,Unit结果是()
println(test)
// 打印了test对象 com.zishi.scala.okk05.Test05_Lambda$$$Lambda$16/0x00000008000d7840@41ee392b
println(test _)
// 函数对象test赋值给一个变量f2
// 函数的类型为:Function0[Unit]
// 0表示函数参数列表为0
// Unit表示函数的返回值为Unit
// val f2: Function0[Unit] = test _
// 这是 val f2: Function0[Unit] = test _的变形
// () => Unit 表示函数f2的类型
val f2: () => Unit = test _
println(f2) //com.zishi.scala.okk05.Test04_Simplify02$$$Lambda$17/0x00000008000d7c40@57d5872c
println("...........")
f2() // 函数调用
// 增加难度
def test1(age: Int): String = {
"hello:" + age
}
//函数的类型为:Function1[Int, String]
// 1表示函数参数列表为1个
// [Int, String]中Int表示函数的参数列表是Int,String表示返回值是String:
// 函数对象的参数最多22个
val f3: Function1[Int, String] = test1
// f4 的函数类型为:(Int) => String, 输入一个Int,返回一个String
// TODO: 这是另外一种表示形式 Function1[Int, String] 等价于 (Int) => String
val f4: (Int) => String = test1
println(f3) // com.zishi.scala.okk05.Test04_Simplify02$$$Lambda$18/0x00000008000d6840@36f0f1be
println(f4) // com.zishi.scala.okk05.Test04_Simplify02$$$Lambda$19/0x00000008000d6040@6ee12bac
f4(4) // 这里是方法调用, 类似Java中的对象调用方法: user.xxxx
}
}