柯里化
- 柯里化是一个过程
- 把一个参数列表中的多个参数, 转换为多个参数列表
- 科里化可以支持隐式转换
[Scala] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
|
object Currying {
"正常方法"
def m 1 (a : Int, b : Int) : Int = a + b
"柯里化方法"
def m 2 (a : Int)(b : Int) = a + b
def m 3 (a : Int)(b : Int, c : Int) = a + b + c
def m 4 (a : Int, b : Int)(c : Int, d : Int) = a + b + c + d
def main(args : Array[String]) : Unit = {
println( "正常方法调用:" + m 1 ( 10 , 20 ))
println( "柯里化方法调用:" + m 2 ( 10 )( 20 ))
println( "柯里化方法调用:" + m 3 ( 10 )( 20 , 30 ))
println( "柯里化方法调用:" + m 4 ( 10 , 20 )( 30 , 40 ))
}
}
|
隐式参数
- 用 implicit 关键字修饰的参数,就是隐式参数
- 隐式参数的值从哪儿取
- 从上下文环境中,最多找到一个和隐式参数类型一致,且用implicit修饰的变量,如果找到多个则报错
- 如果上下文环境中没有,则使用默认值
- 如果找不到,也没有默认值,则报错
- implicit 只能作用于最后一个参数列表,一个参数列表中只能由一个 implicit 关键字
- 关键字只能放在最后一个参数列表中,而且修饰该参数列表中的所有参数
[Scala] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
|
object ImpDemo {
implicit val defalut 1 : Int = 20
// implicit val defalut2: Int = 30
implicit val defalut 3 : Double = 10
def m 1 (a : Int)( implicit b : Int = 10 ) : Int = {
if (a > b) a else b
}
def m 2 (a : Int)( implicit b : Int, c : Double) : Double = a + b + c
def main(args : Array[String]) : Unit = {
println(m 1 ( 5 ))
println(m 1 ( 5 )( 30 ))
println(m 2 ( 10 ))
}
}
|
隐式转换
- 主要指隐式方法和隐式函数
[Scala] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
|
object ImpMethod {
implicit def str 2 int(str : String) : Int = Integer.parseInt(str)
def main(args : Array[String]) : Unit = {
println( 1 to 3 )
"这里发生了隐式转换,这里调用了RichInt的方法"
"implicit 修饰的方法,方法参数是Int,返回值是RichInt"
"当Int 类型上调用to方法,Int上没有这个方法,但是RichInt上有,发现有隐式方法从Int->RichRint"
println( 1 .to( 3 ))
val x : Int = "123"
println(x)
}
}
|
[Scala] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
|
import java.io.File
import scala.io.Source
class RichFile(f : File) {
def read() : String = Source.fromFile(f).getLines().mkString( "\r\n" );
}
object RichFile {
// 隐式转换
implicit def file 2 RichFile(f : File) : RichFile = new RichFile(f)
def main(args : Array[String]) : Unit = {
val path : String = "C:/Users/unkonw_yu/Desktop/scala/rating.json"
val f = new File(path)
val lines = f.read()
println(lines)
}
}
|
- 如果隐式方法和隐式函数都存在,优先使用函数
[Scala] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
|
class RichFile(f : File) {
def read() : String = Source.fromFile(f).getLines().mkString( "\r\n" );
}
object RichFile {
// 隐式转换
implicit def file 2 RichFile(f : File) : RichFile = new RichFile(f)
implicit val file 2 RichFile 2 = (f : File) = > {
println( "调用函数" )
new RichFile(f)
}
def main(args : Array[String]) : Unit = {
val path : String = "C:/Users/unkonw_yu/Desktop/scala/rating.json"
val f = new File(path)
val lines = f.read()
println(lines)
}
}
|
- 可以导入外部的隐式转换 ,类和object导入方式不一样
[Scala] 纯文本查看 复制代码
1
2
3
4
5
6
7
|
import java.io.File
class MyImpl {
implicit def file 2 RichFile(f : File) : RichFile = new RichFile(f)
}
object MyImpl {
implicit def file 2 RichFile(f : File) : RichFile = new RichFile(f)
}
|
[Scala] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
|
class RichFile(f : File) {
def read() : String = Source.fromFile(f).getLines().mkString( "\r\n" );
}
object RichFile {
"引入 object 的隐式方法"
import MyImpl.file 2 RichFile
"引入 class 的隐式方法"
private val imp = new MyImpl
import imp.file 2 RichFile
def main(args : Array[String]) : Unit = {
val path : String = "C:/Users/unkonw_yu/Desktop/scala/rating.json"
val f = new File(path)
val lines = f.read()
println(lines)
}
}
|
泛型
[Scala] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
abstract class Message[T](msg : T) {
def getMsg() : T = msg
}
class IntMsg(msg : Int) extends Message(msg)
class StrMsg(msg : String) extends Message(msg)
object TestMsg {
def main(args : Array[String]) : Unit = {
val msg 1 = new IntMsg( 123 )
println(msg 1 .getMsg())
val msg 2 = new StrMsg( "hello" )
println(msg 2 .getMsg())
}
}
|
[Scala] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
|
class Clothes[ColorTypes]( val color : ColorTypes)
"枚举"
object ColorTypes extends Enumeration {
type CT = Value
val RED = Value( 0 )
val BLACK = Value( 1 )
val GREEN = Value( 2 )
}
object TestMsg {
def main(args : Array[String]) : Unit = {
val colthes 1 = new Clothes[ColorTypes.Value](ColorTypes.RED)
val colthes 2 = new Clothes[CT](ColorTypes.GREEN)
println(colthes 1 .color)
println(colthes 2 .color)
}
}
|
比较器
- Java 中的比较器
- Comparable
- Comparator
- scala中的比较器
- Ordered --> Comparable
- Ordering --> Comparator
[Scala] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
import java.util
import java.util.Collections
class Student( val name : String, val age : Int, val fv : Int) extends Ordered[Student] {
override def compare(that : Student) : Int = this .fv - that.fv
override def toString : String = s "${name},${age},${fv}"
}
object Student {
def main(args : Array[String]) : Unit = {
val sList = new util.ArrayList[Student]()
val s 1 = new Student( "zs" , 23 , 999 )
val s 2 = new Student( "li" , 24 , 998 )
val s 3 = new Student( "ww" , 25 , 997 )
sList.add(s 1 )
sList.add(s 2 )
sList.add(s 3 )
Collections.sort(sList)
println(sList)
Collections.sort(sList, new Ordering[Student]{
override def compare(x : Student, y : Student) : Int = y.fv - x.fv
})
println(sList)
}
}
|
泛型约束上界
- Java
- <T extends P>
- <? extends P>
- Scala
- T <: P
[Scala] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
任意类型比较 "
class ComparTest[T](t1: T, t2: T) {
def myEquals() = t1 == t2
}
" Comparable 的子类 "
class ComparaTest2[T <: Ordered[T]](t1: T, t2: T) {
def myEquals() = t1 compareTo t2
}
object ComparTest {
def main(args: Array[String]): Unit = {
val s1 = new Student(" zs ", 23, 999)
val s2 = new Student(" li ", 24, 998)
val comp1 = new ComparTest[Student](s1, s2)
println(comp1.myEquals())
val comp2 = new ComparTest[Int](1, 2)
println(comp2.myEquals())
" 报错,Int没有混入Ordered特质 "
val comp3 = new ComparaTest2[Int](1, 2)
println(comp3.myEquals())
" 正常运行"
val comp 4 = new ComparaTest 2 [Student](s 1 ,s 2 )
println(comp 4 .myEquals())
}
}
|
下界
[Scala] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
|
object LowerBounds {
val f 1 = (x : Int, y : Int) = > x + y
val f 2 = (a : AnyVal, b : AnyVal) = > a.asInstanceOf[Int] + b.asInstanceOf[Int]
val f 3 = (a : Any, b : Any) = > a
val f 4 = (a : Any, b : AnyRef) = > a
val f 5 = (a : AnyRef, b : AnyRef) = > a
def main(args : Array[String]) : Unit = {
val arr = Array( 1 , 3 , 5 , 7 , 9 )
// def reduce[A1 >: A]
val res 1 = arr.reduce( _ + _ )
val res 2 = arr.reduce(f 1 )
// AnyVal 是 Int 的父类,可以传递
val res 3 = arr.reduce(f 2 )
// Any 是 Int 的顶级父类,可以传递
val res 4 = arr.reduce(f 3 )
// AnyRef 不是 Int 的父类,调用失败
// val res5 = arr.reduce(f4)
// val res6 = arr.reduce(f5)
}
}
|
协变逆变
[XML] 纯文本查看 复制代码
1
2
3
4
5
|
[T] 正常的泛型 不变
[T <: Test] 上界
[T >: Test] 下界
[+T] 协变
[-T] 逆变
|
[Scala] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
class Card[T] {}
class Card[+T] {}
class Card[-T] {}
class Metting[T] {
def metting(c : Card[T]) : Unit = println( "人们代表大会" )
}
// 层级关系
class ChangWei
class Leader extends ChangWei
class Flower extends Leader
object Card {
def main(args : Array[String]) : Unit = {
val metting = new Metting[ChangWei]()
val changweiCart = new Card[ChangWei]
val leaderCart = new Card[Leader]
val flowerCart = new Card[Flower]
"class Card[T]"
metting.metting(changweiCart)
"下面的会报错"
// metting.metting(leaderCart)
// metting.metting(flowerCart)
"class Cart[+T],都不会报错"
metting.metting(changweiCart)
metting.metting(leaderCart)
metting.metting(flowerCart)
"class Cart[-T]"
val leaderMetting = new Metting[Leader]
leaderMetting.metting(changweiCart)
leaderMetting.metting(leaderCart)
"下面代码会报错"
// leaderMetting.metting(flowerCart)
}
}
|
CallByName 和 CallByValue
- 函数调用中的两种形式
- CallByName(传名调用)
- 传递的参数,在调用的时候才会真正的执行
- CallByValue(传值调用)
- 先计算调用的结果,然后再传递
- CallByName(传名调用)
[Scala] 纯文本查看 复制代码
柯里化
隐式参数
隐式转换
泛型
比较器
泛型约束 上界
下界
协变逆变
CallByName 和 CallByValue
- 柯里化是一个过程
- 把一个参数列表中的多个参数, 转换为多个参数列表
- 科里化可以支持隐式转换
[Scala] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
|
object Currying {
"正常方法"
def m 1 (a : Int, b : Int) : Int = a + b
"柯里化方法"
def m 2 (a : Int)(b : Int) = a + b
def m 3 (a : Int)(b : Int, c : Int) = a + b + c
def m 4 (a : Int, b : Int)(c : Int, d : Int) = a + b + c + d
def main(args : Array[String]) : Unit = {
println( "正常方法调用:" + m 1 ( 10 , 20 ))
println( "柯里化方法调用:" + m 2 ( 10 )( 20 ))
println( "柯里化方法调用:" + m 3 ( 10 )( 20 , 30 ))
println( "柯里化方法调用:" + m 4 ( 10 , 20 )( 30 , 40 ))
}
}
|
隐式参数
- 用 implicit 关键字修饰的参数,就是隐式参数
- 隐式参数的值从哪儿取
- 从上下文环境中,最多找到一个和隐式参数类型一致,且用implicit修饰的变量,如果找到多个则报错
- 如果上下文环境中没有,则使用默认值
- 如果找不到,也没有默认值,则报错
- implicit 只能作用于最后一个参数列表,一个参数列表中只能由一个 implicit 关键字
- 关键字只能放在最后一个参数列表中,而且修饰该参数列表中的所有参数
[Scala] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
|
object ImpDemo {
implicit val defalut 1 : Int = 20
// implicit val defalut2: Int = 30
implicit val defalut 3 : Double = 10
def m 1 (a : Int)( implicit b : Int = 10 ) : Int = {
if (a > b) a else b
}
def m 2 (a : Int)( implicit b : Int, c : Double) : Double = a + b + c
def main(args : Array[String]) : Unit = {
println(m 1 ( 5 ))
println(m 1 ( 5 )( 30 ))
println(m 2 ( 10 ))
}
}
|
隐式转换
- 主要指隐式方法和隐式函数
[Scala] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
|
object ImpMethod {
implicit def str 2 int(str : String) : Int = Integer.parseInt(str)
def main(args : Array[String]) : Unit = {
println( 1 to 3 )
"这里发生了隐式转换,这里调用了RichInt的方法"
"implicit 修饰的方法,方法参数是Int,返回值是RichInt"
"当Int 类型上调用to方法,Int上没有这个方法,但是RichInt上有,发现有隐式方法从Int->RichRint"
println( 1 .to( 3 ))
val x : Int = "123"
println(x)
}
}
|
[Scala] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
|
import java.io.File
import scala.io.Source
class RichFile(f : File) {
def read() : String = Source.fromFile(f).getLines().mkString( "\r\n" );
}
object RichFile {
// 隐式转换
implicit def file 2 RichFile(f : File) : RichFile = new RichFile(f)
def main(args : Array[String]) : Unit = {
val path : String = "C:/Users/unkonw_yu/Desktop/scala/rating.json"
val f = new File(path)
val lines = f.read()
println(lines)
}
}
|
- 如果隐式方法和隐式函数都存在,优先使用函数
[Scala] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
|
class RichFile(f : File) {
def read() : String = Source.fromFile(f).getLines().mkString( "\r\n" );
}
object RichFile {
// 隐式转换
implicit def file 2 RichFile(f : File) : RichFile = new RichFile(f)
implicit val file 2 RichFile 2 = (f : File) = > {
println( "调用函数" )
new RichFile(f)
}
def main(args : Array[String]) : Unit = {
val path : String = "C:/Users/unkonw_yu/Desktop/scala/rating.json"
val f = new File(path)
val lines = f.read()
println(lines)
}
}
|
- 可以导入外部的隐式转换 ,类和object导入方式不一样
[Scala] 纯文本查看 复制代码
1
2
3
4
5
6
7
|
import java.io.File
class MyImpl {
implicit def file 2 RichFile(f : File) : RichFile = new RichFile(f)
}
object MyImpl {
implicit def file 2 RichFile(f : File) : RichFile = new RichFile(f)
}
|
[Scala] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
|
class RichFile(f : File) {
def read() : String = Source.fromFile(f).getLines().mkString( "\r\n" );
}
object RichFile {
"引入 object 的隐式方法"
import MyImpl.file 2 RichFile
"引入 class 的隐式方法"
private val imp = new MyImpl
import imp.file 2 RichFile
def main(args : Array[String]) : Unit = {
val path : String = "C:/Users/unkonw_yu/Desktop/scala/rating.json"
val f = new File(path)
val lines = f.read()
println(lines)
}
}
|
泛型
[Scala] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
abstract class Message[T](msg : T) {
def getMsg() : T = msg
}
class IntMsg(msg : Int) extends Message(msg)
class StrMsg(msg : String) extends Message(msg)
object TestMsg {
def main(args : Array[String]) : Unit = {
val msg 1 = new IntMsg( 123 )
println(msg 1 .getMsg())
val msg 2 = new StrMsg( "hello" )
println(msg 2 .getMsg())
}
}
|
[Scala] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
|
class Clothes[ColorTypes]( val color : ColorTypes)
"枚举"
object ColorTypes extends Enumeration {
type CT = Value
val RED = Value( 0 )
val BLACK = Value( 1 )
val GREEN = Value( 2 )
}
object TestMsg {
def main(args : Array[String]) : Unit = {
val colthes 1 = new Clothes[ColorTypes.Value](ColorTypes.RED)
val colthes 2 = new Clothes[CT](ColorTypes.GREEN)
println(colthes 1 .color)
println(colthes 2 .color)
}
}
|
比较器
- Java 中的比较器
- Comparable
- Comparator
- scala中的比较器
- Ordered --> Comparable
- Ordering --> Comparator
[Scala] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
import java.util
import java.util.Collections
class Student( val name : String, val age : Int, val fv : Int) extends Ordered[Student] {
override def compare(that : Student) : Int = this .fv - that.fv
override def toString : String = s "${name},${age},${fv}"
}
object Student {
def main(args : Array[String]) : Unit = {
val sList = new util.ArrayList[Student]()
val s 1 = new Student( "zs" , 23 , 999 )
val s 2 = new Student( "li" , 24 , 998 )
val s 3 = new Student( "ww" , 25 , 997 )
sList.add(s 1 )
sList.add(s 2 )
sList.add(s 3 )
Collections.sort(sList)
println(sList)
Collections.sort(sList, new Ordering[Student]{
override def compare(x : Student, y : Student) : Int = y.fv - x.fv
})
println(sList)
}
}
|
泛型约束 上界
- Java
- <T extends P>
- <? extends P>
- Scala
- T <: P
[Scala] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
任意类型比较 "
class ComparTest[T](t1: T, t2: T) {
def myEquals() = t1 == t2
}
" Comparable 的子类 "
class ComparaTest2[T <: Ordered[T]](t1: T, t2: T) {
def myEquals() = t1 compareTo t2
}
object ComparTest {
def main(args: Array[String]): Unit = {
val s1 = new Student(" zs ", 23, 999)
val s2 = new Student(" li ", 24, 998)
val comp1 = new ComparTest[Student](s1, s2)
println(comp1.myEquals())
val comp2 = new ComparTest[Int](1, 2)
println(comp2.myEquals())
" 报错,Int没有混入Ordered特质 "
val comp3 = new ComparaTest2[Int](1, 2)
println(comp3.myEquals())
" 正常运行"
val comp 4 = new ComparaTest 2 [Student](s 1 ,s 2 )
println(comp 4 .myEquals())
}
}
|
下界
[Scala] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
|
object LowerBounds {
val f 1 = (x : Int, y : Int) = > x + y
val f 2 = (a : AnyVal, b : AnyVal) = > a.asInstanceOf[Int] + b.asInstanceOf[Int]
val f 3 = (a : Any, b : Any) = > a
val f 4 = (a : Any, b : AnyRef) = > a
val f 5 = (a : AnyRef, b : AnyRef) = > a
def main(args : Array[String]) : Unit = {
val arr = Array( 1 , 3 , 5 , 7 , 9 )
// def reduce[A1 >: A]
val res 1 = arr.reduce( _ + _ )
val res 2 = arr.reduce(f 1 )
// AnyVal 是 Int 的父类,可以传递
val res 3 = arr.reduce(f 2 )
// Any 是 Int 的顶级父类,可以传递
val res 4 = arr.reduce(f 3 )
// AnyRef 不是 Int 的父类,调用失败
// val res5 = arr.reduce(f4)
// val res6 = arr.reduce(f5)
}
}
|
协变逆变
[XML] 纯文本查看 复制代码
1
2
3
4
5
|
[T] 正常的泛型 不变
[T <: Test] 上界
[T >: Test] 下界
[+T] 协变
[-T] 逆变
|
[Scala] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
class Card[T] {}
class Card[+T] {}
class Card[-T] {}
class Metting[T] {
def metting(c : Card[T]) : Unit = println( "人们代表大会" )
}
// 层级关系
class ChangWei
class Leader extends ChangWei
class Flower extends Leader
object Card {
def main(args : Array[String]) : Unit = {
val metting = new Metting[ChangWei]()
val changweiCart = new Card[ChangWei]
val leaderCart = new Card[Leader]
val flowerCart = new Card[Flower]
"class Card[T]"
metting.metting(changweiCart)
"下面的会报错"
// metting.metting(leaderCart)
// metting.metting(flowerCart)
"class Cart[+T],都不会报错"
metting.metting(changweiCart)
metting.metting(leaderCart)
metting.metting(flowerCart)
"class Cart[-T]"
val leaderMetting = new Metting[Leader]
leaderMetting.metting(changweiCart)
leaderMetting.metting(leaderCart)
"下面代码会报错"
// leaderMetting.metting(flowerCart)
}
}
|
CallByName 和 CallByValue
- 函数调用中的两种形式
- CallByName(传名调用)
- 传递的参数,在调用的时候才会真正的执行
- CallByValue(传值调用)
- 先计算调用的结果,然后再传递
- CallByName(传名调用)
[Scala] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
|
object CallByNameAndValue {
def getCurTime() = {
println( "调用 method" )
System.currentTimeMillis()
}
def callByValie (time : Long) : Long = {
println( "call by value" )
time
}
def callByName(time : = > Long) : Long = {
println( "call by name" )
time
}
def main(args : Array[String]) : Unit = {
"先执行getCurTime获取当前时间,然后传递给callByValue方法"
callByValie(getCurTime())
"先执行callByName方法,当需要用到参数的时候,才取计算结果"
callByName(getCurTime())
}
}
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
|
object CallByNameAndValue {
def getCurTime() = {
println( "调用 method" )
System.currentTimeMillis()
}
def callByValie (time : Long) : Long = {
println( "call by value" )
time
}
def callByName(time : = > Long) : Long = {
println( "call by name" )
time
}
def main(args : Array[String]) : Unit = {
"先执行getCurTime获取当前时间,然后传递给callByValue方法"
callByValie(getCurTime())
"先执行callByName方法,当需要用到参数的时候,才取计算结果"
callByName(getCurTime())
}
}
|