Scala语言编码高级特性
1、函数复习
代码实现:
package org.apache.scala.day06
/**
* 函数复习
*/
object Demo001_Function {
//定义一个函数f1,参数是两个Int类型,返回值是一个Int类型
val f1 = (x: Int, y: Int) => x + y
//再定义一个函数f2
val f2 = (m: Int, n: Int) => m * n
val f3 = (x: Int) => x
// 函数其实可以简化(正确方式1)
val f4 = 1 + (_: Int)
// 函数其实可以简化(正确方式2)
val f5: Int => Int = 1 + _
def main(args: Array[String]): Unit = {
println(f1(2, 3))
println(f2(2, 3))
println(f3(3))
println(f4(4))
println(f5(4))
}
}
打印输出:
2、函数传参
比如:
- 定义一个方法,方法m2参数要求是一个函数,函数的参数必须是两个Int类型,返回值类型也是Int类型
def m1(f: (Int, Int) => Int): Int = f(2, 6)
- 定义一个需要两个Int类型参数的方法
def m2(x: Int, y: Int): Int = x + y
- 定义一个计算数据不被写死的方法
def m3(f: (Int, Int) => Int, x: Int, y: Int): Int = f(x, y)
- 定义一个函数f1,参数是两个Int类型,返回值是一个Int类型
val f1 = (x: Int, y: Int) => x + y
- 再定义一个函数f2
val f2 = (m: Int, n: Int) => m * n
- 定义一个传入函数的函数
val f3 = (f: (Int, Int) => Int, x: Int, y: Int) => f(x, y)
完整代码实现:
package org.apache.scala.day06
/**
* 描述:函数传参
*/
object Demo002_HighLevel {
//定义一个方法
//方法m2参数要求是一个函数,函数的参数必须是两个Int类型
//返回值类型也是Int类型
def m1(f: (Int, Int) => Int): Int = f(2, 6)
// 定义一个需要两个Int类型参数的方法
def m2(x: Int, y: Int): Int = x + y
// 定义一个计算数据不被写死的方法
def m3(f: (Int, Int) => Int, x: Int, y: Int): Int = f(x, y)
// 定义一个函数f1,参数是两个Int类型,返回值是一个Int类型
val f1 = (x: Int, y: Int) => x + y
// 再定义一个函数f2
val f2 = (m: Int, n: Int) => m * n
// 定义一个传入函数的函数
val f3 = (f: (Int, Int) => Int, x: Int, y: Int) => f(x, y)
//main方法
def main(args: Array[String]) {
//调用m1方法,并传入f1函数
val r1 = m1(f1)
println(r1)
//调用m1方法,并传入f2函数
val r2 = m1(f2)
println(r2)
// 调用m3方法, 传入f1函数
val result1 = m3(f1, 2, 4)
println(result1)
// 调用m3方法,传入f2函数
val result2 = m3(f2, 2, 4)
println(result2)
// 调用m3方法, 传入m2方法作为参数
println(m3(m2, 2, 4))
// 调用f3函数, 传入f1函数
println(f3(f1, 3, 4))
// 调用f3函数, 传入f2函数
println(f3(f2, 3, 4))
}
}
打印输出:
3、Scala编程语言的闭包测试
案例1,代码实现:
package org.apache.scala.day06
/**
* 描述: Scala编程语言的闭包测试
*/
object Demo003_Closure {
def main(args: Array[String]): Unit = {
var result = bibao()
println(result(2))
println(result(2))
println(result(2))
println(result(2))
}
// bibao是一个函数
var bibao = () => {
var sum = 0
var add_sum = (x: Int) => {
sum += x
sum
}
add_sum
}
}
打印输出:
案例2,代码实现:
package org.apache.scala.day06
/**
* 描述: Scala编程语言的闭包测试
*/
object Demo003_Closure01 {
def main(args: Array[String]): Unit = {
// 如何在这个ff函数的外部访问到number这个变量的值
def ff1(): Unit = {
var number = 100
}
// 定义一个函数ff,它的返回值是这个number, 并且这个函数作为ff2的返回值
def ff2() = {
var number = 100
val ff = () => {
number
}
ff
}
val resultFunc = ff2()
val result = resultFunc()
println(result)
// 调用过程中的细节
def ff3() = {
var number = 100
val ff = (a: Int) => {
number += a
number
}
ff
}
val resultFunc3 = ff3()
val result3 = resultFunc3(2)
val result4 = resultFunc3(2)
val result5 = resultFunc3(2)
println(result3, result4, result5)
}
}
打印输出:
案例3,代码实现:
package org.apache.scala.day06
/**
* 描述: Scala编程语言的闭包测试
*/
object Demo003_Closure02 {
def main(args: Array[String]): Unit = {
// 定义一个函数ff,它的返回值是这个number, 并且这个函数作为ff2的返回值
def ff2() = {
var number = 100
number
}
val result = ff2
println(result)
}
}
打印输出:
4、 柯里化
原因:定义的方法的实现体是一个要接受另外一个参数的函数
概念:柯里化(Currying)是把接受多个参数的函数变换成接受一个
单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术。
案例1,代码实现:
package org.apache.scala.day06
/**
* 描述: 柯里化
*/
object Demo004_CurryTest1 {
def main(args: Array[String]): Unit = {
// 定义一个方法,但是方法的实现体是一个函数
def m1(x: Int) = (y: Int) => x * y
val func = m1(3)
val result = func(5)
println(result)
println(m1(3)(5))
// 事实上这种方式的调用就得等同于是:
def m2(x: Int)(y: Int = 10) = x * y
println(m2(3)(5))
println(m2(9)()) // √√√√√
// println(m2(9) // xxxxx
def m3(x: Int)(implicit y: Int = 10) = x * y
println(m3(3)(5))
println(m3(3))
println(m3(3)())
}
}
打印输出:
案例2,代码实现:
package org.apache.scala.day06
/**
* 描述: 柯里化 测试
*/
object Demo005_CurryTest2 {
def multiply1(x: Int)(y: Int) = x * y
//柯里化就是把参数可以分开来,把部分函数参数可以用下划线来代替
def multiply2 = multiply1(2) _
// 一个普通的方法,接受两个Int类型参数做乘积
def multiply3(x: Int, y: Int) = x * y
def multiply4(x: Int, y: Int = 10) = x * y
def multiply5(x: Int)(y: Int = 10) = x * y
def main(args: Array[String]): Unit = {
println(multiply1(2)(4))
println(multiply2(4))
// 跟柯里化的函数在结果上没有区别,那到底有什么区别呢?
println(multiply3(2, 4))
println(multiply4(4))
println(multiply5(4)())
}
}
打印输出:
5、隐式参数
代码实现:
package org.apache.scala.day06
/**
* 描述: Scala编程语言 隐式参数
*/
object Demo006_ImplicitParam {
// 正常的普通方法
def add(x: Int, y: Int) = x + y
// 柯里化的方法
def add2(x: Int)(y: Int) = x + y
// 如果变成下面这种形式:
def add3(x: Int)(implicit y: Int = 10) = x + y
implicit var aa: Int = 3
def main(args: Array[String]): Unit = {
println(add(2, 3))
// 不能只传一个参数取使用,必须要传入两个参数
println(add2(2)(3))
// 调用带隐式参数的函数
println(add3(2))
}
}
打印输出:
6、柯里化函数的隐式参数
代码实现:
package org.apache.scala.day06
/**
* 描述: 柯里化函数的隐式参数
* 时间:2021.07.24
*/
object Demo007_ImplicitParam2 {
/**
* 第一个参数是要换算成美元的人民币数目
* 第二个参数是汇率
*/
def rmb(dollar: Double)(implicit rate: Double = 6) = dollar * rate
def main(args: Array[String]): Unit = {
println(rmb(100))
println(rmb(100)(7))
// 引入隐式转换值,所以第二个参数被隐式的转换成了6.66
import MyPredefX._
println(rmb(100))
}
}
object MyPredefX {
// 声明一个Double类型的隐式转换值
implicit var current_rate: Double = 6.66
}
打印输出:
7、隐式转换
代码实现:
package org.apache.scala.day06
import java.io.File
import scala.io.Source
/**
* 描述: Scala编程语言的隐式转换
*/
object FileImplicit {
def main(args: Array[String]): Unit = {
try {
import MyPredef._
val file = new File("C:\\words.txt").readAll()
println(file)
// throw new Exception("xxx")
} catch {
case e: Exception => println(e)
}
}
}
class RichFile(f: File) {
def readAll(): String = {
Source.fromFile(f).mkString
}
}
object MyPredef {
implicit def fileToRichFile(f: File): RichFile = new RichFile(f)
}
打印输出:
8、隐式转换测试
案例1,代码实现:
package org.apache.scala.day06
/**
* 描述: Scala编程语言的隐式转换测试例子
*/
object ImplicitTest3 {
def main(args: Array[String]): Unit = {
val ticketHouse = new TicketHouse()
val young = new Young("Young")
val older = new Older("Older")
val worker = new Worker("Worker")
val adult = new Worker("Adult")
import ObjectImplicit._
// ticketHouse.buyTicket(worker) // 报错
// ticketHouse.buyTicket(adult) // 报错
ticketHouse.buyTicket(young)
ticketHouse.buyTicket(older)
}
}
object ObjectImplicit {
/* implicit def object2special(obj:SpecialPerson):SpecialPerson={
if(obj.getClass == classOf[Young]){
val young = obj.asInstanceOf[Young]
new SpecialPerson(young.name)
}else if(obj.getClass == classOf[Older]){
val older = obj.asInstanceOf[Older]
new SpecialPerson(older.name)
}else{
new SpecialPerson("NULL")
}*/
implicit def object2special1(obj: Young): SpecialPerson = new SpecialPerson(obj.name)
implicit def object2special2(obj: Older): SpecialPerson = new SpecialPerson(obj.name)
}
//特殊人群
class SpecialPerson(var name: String)
//特殊人群之一
class Young(var name: String)
//特殊人群之一
class Older(var name: String)
//正常人群之一
class Worker(var name: String)
//正常人群之二
class Adult(var name: String)
class TicketHouse {
def buyTicket(p: SpecialPerson): Unit = {
println(p.name + "票给你!!爽去吧!!");
}
}
打印输出:
案例2,代码实现:
package org.apache.scala.day06
/**
* 隐式转换
*/
object Demo009_Implicit_Type {
def main(args: Array[String]): Unit = {
// 定义一个隐式转换,能够、把一个double类型的数编程int类型。
implicit def double2Int(a: Double) = a.toInt
// implicit def double2String(a:Double) = a.toString
// implicit def string2Int(s:String) = s.toInt
// 定义三个方法
def sum1(x: Int, y: Int) = x + y
def sum2(x: Int, y: Double) = x + y
def sum3(x: Double, y: Double) = x + y
// 使用
println(sum1(1, 2.0)) // 触发隐式转换
println(sum2(1, 2)) // 触发隐式转换
println(sum3(1, 2)) // 触发隐式转换
}
}
打印输出: