文章目录
方法与函数
函数(又称函数值/匿名函数)
- 定义在任何地方:函数可以定义在类的成员中,也可以定义在顶层(即不在任何类或对象中这是scala3特性)。
- 不能访问类的私有成员:除非函数定义在类内部,否则它不能访问类的私有成员。
- 是一等公民:函数可以作为值传递,可以赋值给变量,可以存储在数据结构中,可以作为其他函数的参数或返回值。
- 可以使用函数字面量定义:函数可以使用
=>
符号定义匿名函数。
=>
符号在 Scala 中用于定义匿名函数,它提供了一种简洁的方式来定义函数,特别是在需要将函数作为参数传递给其他函数时。匿名函数是函数式编程的重要组成部分,使代码更加灵活和可组合。
在 Scala 中,匿名函数(也称为 lambda 表达式)通常与 val
一起使用,而不是 var
。这是因为匿名函数本身是一个值,并且你通常不希望重新赋值给这个函数。‘
定义方法
val 函数名:函数类型=>返回类型 = (实际传入参数)=>表达式
简洁形式:这种形式的匿名函数直接将参数和表达式放在 =>
符号的两侧。这种形式的函数没有函数体,因此它的返回值是 =>
右侧表达式的结果。
// 定义参数类型返回类型,定义参数,表达式
val ldsx2: (Int, Int) => Unit = (a, b) => println(a, b)
// 定义参数 参数类型,表达式
val ldsx2:(a:Int, b:Int) => println(a, b)
带函数体形式:这种形式的匿名函数使用花括号 {}
来定义函数体。函数体中的最后一个表达式是函数的返回值。
val ldsx3: (Int, Int) => Unit = (a, b) => {
println(a, b)
}
定义部分
(Int, Int) => Unit
是 Scala 中的一种函数类型表示法,它表示一个接受两个 Int
类型参数并返回 Unit
类型结果的函数。这种表示法通常用于定义匿名函数(lambda 表达式)或高阶函数。
具体来说:
(Int, Int)
: 这部分表示函数接受两个参数,这两个参数的类型都是Int
。=>
: 这个符号表示函数类型。Unit
: 这部分表示函数的返回类型。Unit
是 Scala 中的一个特殊类型,表示没有值,类似于 Java 中的void
。
因此,(Int, Int) => Unit
表示一个函数类型,这个函数接受两个 Int
类型的参数,并返回 Unit
类型的结果。这意味着这个函数执行一些操作,但不返回任何值。
以下是一个使用 (Int, Int) => Unit
函数类型的例子:
表达式部分
(a, b)
: 这部分定义了匿名函数的参数列表。这个匿名函数接受两个参数,分别是a
和b
。=>
: 这个符号表示函数字面量的开始。{ println(a, b) }
: 这部分是匿名函数的主体,它是一个代码块。这个代码块包含一个表达式println(a, b)
,这个表达式打印参数a
和b
的值。
注意
在 Scala 中,当匿名函数的主体只包含一个表达式时,花括号 {}
可以省略。同样,当匿名函数只有一个参数时,圆括号 ()
也是可选的。这些简化使得代码更简洁,但也保持了代码的可读性。
-
花括号
{}
:
花括号用于定义匿名函数的主体。当匿名函数的主体只包含一个表达式时,花括号可以省略。例如:// 使用花括号 val result1 = ary.filter( n => { n == 2 }) // 不使用花括号 val result2 = ary.filter(n => n == 2)
在这两个例子中,
n => n == 2
是一个匿名函数,它接受一个参数n
并返回一个布尔值,表示n
是否等于2
。当匿名函数的主体只有一个表达式时,花括号是可选的。 -
圆括号
()
:
圆括号用于定义匿名函数的参数列表。当匿名函数只有一个参数时,圆括号也是可选的。例如:// 使用圆括号 val result3 = ary.filter((n) => n == 2) // 不使用圆括号 val result4 = ary.filter(n => n == 2)
在这两个例子中,
n => n == 2
和(n) => n == 2
都是有效的匿名函数。当匿名函数只有一个参数时,圆括号是可选的。
单参数函数
val square: Int => Int = x => x * x
// 调用匿名函数
println(square(5)) // 输出 25
val square = x:Int => x*x
在这个例子中,square
是一个匿名函数,它接受一个 Int
类型的参数 x
,并返回 x
的平方。
多参数函数
val add: (Int, Int) => Int = (a, b) => a + b
// 调用匿名函数
println(add(3, 4)) // 输出 7
在这个例子中,add
是一个匿名函数,它接受两个 Int
类型的参数 a
和 b
,并返回它们的和。
val add: (Int, Int) => Int = (a, b) => a + b
这行代码定义了一个名为 add
的值,它实际上是一个匿名函数(也称为函数字面量)。下面是详细的语法解释:
val add
:val
是一个关键字,用于定义一个不可变的值(类似于常量)。add
是这个值的名称。
: (Int, Int) => Int
:- 这部分定义了
add
的类型。 (Int, Int)
表示这个函数接受两个Int
类型的参数。=>
符号表示函数的参数和返回值之间的映射。Int
表示这个函数返回一个Int
类型的结果。- 因此,
(Int, Int) => Int
表示这是一个接受两个Int
参数并返回Int
结果的函数类型。
- 这部分定义了
= (a, b) => a + b
:=
符号用于将右侧的匿名函数赋值给左侧的add
。(a, b)
表示匿名函数的参数列表,其中a
和b
是两个Int
类型的参数。=>
符号表示参数和函数体之间的映射。a + b
是函数体,表示将参数a
和b
相加并返回结果。
综上所述,这行代码定义了一个名为 add
的值,它是一个接受两个 Int
参数并返回它们之和的匿名函数。你可以像调用普通函数一样调用 add
:
println(add(3, 4)) // 输出 7
在这个例子中,add(3, 4)
调用了匿名函数 (a, b) => a + b
,其中 a
被赋值为 3
,b
被赋值为 4
,函数体 a + b
计算结果为 7
,并打印出来。
函数作为参数传递
匿名函数通常用作高阶函数的参数。高阶函数是可以接受函数作为参数或返回函数作为结果的函数。
object Scalafunc {
def main(args:Array[String]):Unit={
// 匿名函数定义
val fc :(Int,Int)=>Int = (a,b) =>a+b
println(fc(1,2))
greet("ldsx")
lambda_func((a,b)=>a+b,1,"3")
}
def greet(name: String): Unit = {
println(s"Hello, $name!")
}
def lambda_func(func :(Int,String)=>String,a:Int,b:String):Unit={
val data = func(a,b)
println(data)
}
}
在lambda_func
中,参数分为二部分,共三个
func :(Int,String)=>String
- 第一个参数接受匿名函数名称
func
- 这个参数目是设置好匿名函数名称,确认匿名函数
func
接受的参数 与返回的数据类型
- 第一个参数接受匿名函数名称
a:Int,b:String
a,b
为func
所需的参数,但是需要通过lambda_func
传入函数内部给func
调用
方法
- 定义在类或对象中:方法定义在类或对象内部,是类或对象的一部分。
- 可以访问类的成员:方法可以访问类的私有成员(如变量和其他方法)。
- 不是一等公民:方法不能直接作为值传递,不能赋值给变量,不能存储在数据结构中,也不能作为其他方法的参数或返回值。
- 使用
def
关键字定义:方法使用def
关键字定义。
object Scalafunc {
val ldsx = "hello"
def main(args:Array[String]):Unit={
// 匿名函数定义
val fc :(Int,Int)=>Int = (a,b) =>a+b
println(fc(1,2))
greet("ldsx")
// 访问成员
println(ldsx)
}
def greet(name: String): Unit = {
println(s"Hello, $name!")
}
}
将方法转换为函数
虽然方法不是一等公民,但你可以通过将方法转换为函数来使用它。这可以通过在方法后面加上一个下划线 _
来实现。
class MyClass {
def greet(name: String): String = {
s"Hello, $name!"
}
}
val myObject = new MyClass
val greetFunction: String => String = myObject.greet _
println(greetFunction("Scala")) // 输出 "Hello, Scala!"
在这个例子中,myObject.greet _
将 greet
方法转换为了一个函数。
方法的返回值
在 Scala 中,函数和方法不需要显式地使用 return
关键字来返回值。Scala 的函数和方法会返回其最后一个表达式的结果,
def add(a: Int, b: Int): Int = {
a + b // 这个表达式的结果会被返回
}
val result = add(3, 4)
println(result) // 输出 7
在 Scala 中,过程方法是一种不返回任何值的方法。过程方法的返回类型是 Unit
,你可以省略 Unit
,因为编译器可以推断出返回类型。以下是一个过程方法的示例
// 定义Unit过程方法不会有返回值
def fun3(a:String):Unit={
var info_d = "aaaa"
info_d
}
// 设置返回值将会返回最后一个表达式 info_d
def fun4(a:String):String={
var info_d = "aaaa"
info_d
}
// 当最后一个表达式是print 则报错,因为print
def fun4(a: String): String = {
var info_d = a
info_d
println(info_d)
}
// 不定义返回值 自动编译判断,当你返回表达式有结果时为过程函数,当返回值时为返回值函数
def fun4(a: String) = {
var info_d = a
println(info_d,111)
a
}
总结
- 方法 是类或对象的一部分,可以访问类的私有成员,但不是一等公民。
- 函数 可以在任何地方定义,不能直接访问类的私有成员(除非在类内部定义),但它们是一等公民,具有更大的灵活性和功能性。