一、高阶函数
作为值的函数
我们可以将算法封装成函数,传递给一个方法。
// 1. 创建函数,将数字转换为小星星
val func:Int => String = (num:Int) => "*" * num
// 2. 创建列表,执行转换
val starList = (1 to 10).map(func)
// 3. 打印测试
println(starList)
匿名函数
val starList = (1 to 10).map(num => "*" * num)
// 使用下划线来简化代码编写
var starList2 = (1 to 10).map("*" * _)
闭包
闭包就是一个函数,只不过这个函数的返回值依赖于声明在函数外部的变量。可以简单认为,就是可以访问不在当前作用域范围的一个函数。
val y = 10
// 定义一个函数,访问函数作用域外部的变量
val add:Int => Int = (x:Int) => x + y
println(add(1))
柯里化
柯里化是指将原先接受多个参数的方法转换为多个只有一个参数的参数列表的过程。
// 1. 定义一个方法(柯里化), 计算两个Int类型的值
def calculate(a:Int, b:Int)(calc:(Int, Int) => Int) = {
calc(a, b)
}
// 2. 调用柯里化方法
def main(args: Array[String]): Unit = {
println(calculate(1, 2)(_ + _))
println(calculate(1, 2)(_ * _))
println(calculate(1, 2)(_ - _))
}
二、隐式转换和隐式参数
隐式转换
所谓隐式转换,是指以 implicit 关键字声明的带有单个参数的方法。它是自动被调用的,自动将某种类型转换为另外一种类型。
使用步骤:
- 在 object 中定义隐式转换方法(使用 implicit)
- 在需要用到隐式转换的地方,引入隐式转换(使用 import)
- 自动调动隐式转化后的方法
// 1. 创建扩展类,实现对File的扩展,读取文件内容
class RichFile(val file:File) {
def read() = {
// 将文件内容读取为字符串
Source.fromFile(file).mkString
}
}
// 2. 创建隐式转换
object ImplicitDemo {
// 将File对象转换为RichFile对象
implicit def fileToRichFile(file:File) = new RichFile(file)
}
// 3. 导入隐式转换,测试读取文件内容
def main(args: Array[String]): Unit = {
val file = new File("./data/1.txt")
import ImplicitDemo.fileToRichFile
// 调用隐式转换的方法
println(file.read())
}
隐式转换的时机:
- 当对象调用类中不存在的方法或者成员时,编译器会自动将对象进行隐式转换
- 当方法中的参数的类型与目标类型不一致时
自动导入隐式转换方法
在 Scala 中,如果在当前作用域中有隐式转换方法,会自动导入隐式转换。
// 1. 创建扩展类,实现对File的扩展,读取文件内容
class RichFile(val file:File) {
def read() = {
// 将文件内容读取为字符串
Source.fromFile(file).mkString
}
}
// 3. 导入隐式转换,测试读取文件内容
def main(args: Array[String]): Unit = {
// 2. 创建隐式转换
// 将File对象转换为RichFile对象
implicit def fileToRichFile(file:File) = new RichFile(file)
val file = new File("./data/1.txt")
// 调用隐式转换的方法
println(file.read())
}
隐式参数
方法可以带有一个标记为 implicit 的参数列表,编译器会查找缺省值,提供给该方法。
定义:
- 在方法后面添加一个参数列表,参数使用 implicit 修饰
- 在 object 中定义 implicit 修饰的隐式值
- 调用方法,可以不传入 implicit 修饰的参数列表,编译器会自动查找缺省值
- 和隐式转换一样,可以使用 import 手动导入隐式参数
- 如果在当前作用域定义了隐式值,会自动进行导入
// 1. 定义一个方法,这个方法有一个隐式参数
def quote(what:String)(implicit delimiters:(String, String)) = {
delimiters._1 + what + delimiters._2
}
// 2. 定义一个隐式参数
object implicitDemo {
implicit val delimeterParam = ("<<", ">>")
}
// 3. 调用方法执行测试
def main(args: Array[String]): Unit = {
import implicitDemo._
println(quote("你好")) // <<你好>>
}