Scala中函数与方法的区别、定义方式及特性技术问询
Scala中方法与函数的真实区别、定义方式及特性
嘿,这个问题问得特别到位!Scala里方法(method)和函数(function)确实容易让人混淆,我来给你拆解清楚它们的核心差异、定义方式和各自的特性~
一、本质差异:依附性 vs 一等公民
最核心的区别在于:
- 方法是类、对象或者包对象的成员,本质上是JVM层面的传统方法,它必须依附于某个“宿主”才能存在和调用。
- 函数是Scala的一等公民,它本身是
FunctionN(N是参数个数)特质的实例,是一个独立的对象,可以像普通变量一样被赋值、传递、存储,完全不需要依附任何宿主。
二、定义方式
1. 方法的定义:用def关键字
方法只能用def来定义,常见的场景有三种:
// 1. 类中的实例方法,需要创建类的实例才能调用 class Calculator { def add(a: Int, b: Int): Int = a + b } // 2. 单例对象中的方法,可直接通过对象名调用 object StringTool { def trimAndUpper(s: String): String = s.trim.toUpperCase } // 3. 顶级方法(直接写在源文件中),属于默认的包对象,可直接调用 def multiply(x: Int, y: Int): Int = x * y
方法还支持很多实用特性,比如默认参数、可变参数:
// 默认参数 def greet(name: String = "Guest"): Unit = println(s"Hello, $name!") // 可变参数 def printAll(items: String*): Unit = items.foreach(println)
2. 函数的定义:多种方式,常用val/var绑定
函数的定义方式更灵活,核心是创建一个FunctionN实例,常见的写法有:
- 绑定匿名函数到变量:最常用的方式,用
val(一般函数不可变)定义:
// 显式指定类型 val addFunc: (Int, Int) => Int = (a, b) => a + b // 让Scala自动推导类型 val squareFunc = (x: Int) => x * x
- 把方法转成函数:用下划线
_语法,把已有的方法转换成函数实例:
def add(a: Int, b: Int): Int = a + b // 把add方法转成函数 val addFunc = add _
- 匿名函数直接使用:不需要绑定变量,直接作为参数传递给其他方法/函数:
List(1, 2, 3).map(x => x * 2) // 这里的x=>x*2就是匿名函数
- 显式实现
FunctionN特质:这种写法比较繁琐,一般用于理解原理:
val subtractFunc = new Function2[Int, Int, Int] { override def apply(a: Int, b: Int): Int = a - b }
三、各自特性
方法的特性
- 必须依附于类、对象或包对象,无法独立存在;
- 支持方法重载(相同方法名,不同参数列表);
- 可以使用
this关键字访问当前类的成员; - 支持默认参数、可变参数,还能使用
return关键字(虽然Scala不推荐); - 在JVM编译后,就是普通的Java方法,和Java的方法本质一致。
函数的特性
- 一等公民:可以作为参数传递给其他方法/函数,也可以作为返回值返回;
- 可以赋值给变量,存储在集合(比如List、Map)中;
- 本身是对象,自带
andThen、compose等方法,用来组合多个函数; - 可以捕获外部环境的变量,形成闭包;
- 没有重载的概念,每个函数都是独立的实例,即使参数列表相同,也是不同的对象。
补充:调用方式的小区别
- 方法调用:如果是类的实例方法,需要先创建实例再调用;单例对象或顶级方法可以直接调用。比如
new Calculator().add(1,2)、StringTool.trimAndUpper(" hello ")。 - 函数调用:本质是调用函数的
apply方法,Scala会自动省略apply,所以addFunc(1,2)其实等同于addFunc.apply(1,2)。
内容的提问来源于stack exchange,提问作者user9715375
相关产品推荐
相关产品推荐

