1、柯里化
实例:
首先我们定义一个函数:
def add(x:Int,y:Int)=x+y
那么我们应用的时候,应该是这样用:add(1,2)
现在我们把这个函数变一下形:
def add(x:Int)(y:Int) = x + y
那么我们应用的时候,应该是这样用:add(1)(2),最后结果都一样是3,这种方式(过程)就叫柯里化。
完整实例:
package Scala3
object Test {
def k1(x:Int)(y:Int):Int = x * y
def main(args: Array[String]): Unit = {
val i = k1(2)(3)
println(i)
}
}
2、隐式参数转换
(1) 隐式转换简介
在scala语言当中,隐式转换是一项强大的程序语言功能,它不仅能够简化程序设计,也能够使程序具有很强的灵活性。
实例:
object Test {
/**
* 隐式函数
* 1)首先去全局里面去找,如果找到了就用全局里面的那个变量
* 2)如果找不到就到局部去找
* 找到到一直 唯一能匹配上
*/
implicit var z : Int = 100
def k1(x:Int)(implicit y:Int = 6):Int = x + y
def main(args: Array[String]): Unit = {
val i = k1(22)
println(i)
}
}
结果:
122
如果这样写 val i = k1(22)() 就会直接找 def k1(x:Int)(implicit y:Int = 6):Int = x + y 这个里面的
implicit var z : Int = 100
def k1(x:Int)(implicit y:Int = 6):Int = x + y
def main(args: Array[String]): Unit = {
import Myimp.h
val i = k1(22)()
println(i)
}
}
结果:
28
隐式函数总结:
隐式参数:
1:关键字 implicit
2:作用域:先去找全局的,再找局部的
3:要找唯一能匹配上的,如果有多个条件都满足,就报错。
4:implicit 都需要在object里面去使用
为什么Int里面没有to方法:
1 to 10这个类型:
package Scala3
object lession2 {
def main(args: Array[String]): Unit = {
println(1 to 10)
}
}
结果:
Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
原因:
1 to 10
Int: 的确调用了to方法,但是结果在源码里面没有找到
RichInt: 我们在里面找到了一个to方法
new scala.runtime.RichInt(1).to(10)
如果我有这么样的一个隐士转换的关系:Int -> RichInt
隐士转换发生时机:
1)当一个对象去调用某个方法,但是这个对象并不具备这个方法。
这个时候会触发隐士转换,会把这个对象(偷偷的)隐士转换为具有这个方法的那个对象。
Int 1 去调用 to方法。 这个时候1 不具备这个方法。
Int 1 => RichInt 1
这个时候就需要声明一个隐士转换的方法: Int => RichInt
1 to 10 Int 没有to方法
RichInt 有to方法
验证:看一下源码里面有没有这样的一个隐士的方法,把一个Int类型的数,转换成为一个RichInt的数的这样的方法。
implicit def intWrapper(x: Int): runtime.RichInt完整实例:
主代码:
import scala.io.Source
import MyPredef._
class RichFile(f:File){
def read():String = {
Source.fromFile(f).mkString
}
}
object Test {
def main(args: Array[String]): Unit = {
val file = new File("F:\\Scala\\Scala\\第四天\\文档\\第四天.txt").read()
println(file)
}
}
副代码:
package Scala3.lession3
import java.io.File
object MyPredef {
implicit def file2RichFile(file: File)=new RichFile(file)
}
超人会飞代码:
package Scala3.lession3
class Man(var name: String)
class Superman{
def fly(): Unit={
println("我会飞")
}
}
object Test1 {
implicit def mansuperman(man: Man):Superman=new Superman
def main(args: Array[String]): Unit = {
new Man("xiaoma").fly
}
}
分类人群买票实例:
package Scala3.lession3
//特殊人群
class SpecialPerson(var name:String)
//特殊人群之一
class Student(var name:String)
//特殊人群之一
class Older(var name:String)
//正常人群
class Worker(var name: String)
class TickeHouse{
def buyTicket(p:SpecialPerson): Unit={
println(p.name+"票到手!!")
}
}
object MyPredef1 {
implicit def objectspecial(obj:Object):SpecialPerson={
if (obj.getClass == classOf[Student]) {
val student = obj.asInstanceOf[Student]
new SpecialPerson(student.name)
} else if (obj.getClass == classOf[Older]) {
val older = obj.asInstanceOf[Older]
new SpecialPerson(older.name)
} else {
new SpecialPerson("NULL")
}
}
}
object Test2{
def main(args: Array[String]): Unit = {
val house = new TickeHouse
val sa = new Student("aaaa")
val cccc = new Older("cccc")
val lulaoshi = new Worker("lulaoshi")
import MyPredef1._
house.buyTicket(cccc)
}
}
3、上界和下界
主代码:
package Scala3.lession6
object Test {
def main(args: Array[String]): Unit = {
val array = Array[Boy](new Boy("吴彦祖",9),new Boy("李浩诗",99),new Boy("撒本你",999))
val sorted = array.sorted
for (b <- sorted){
println(b.name + " "+ b.faceValue)
}
}
}
package Scala3.lession6
class Boy (var name: String,var faceValue: Int) extends Comparable[Boy]{
override def compareTo(o: Boy): Int = {
o.faceValue - this.faceValue
}
}
结果:
撒本你 999
李浩诗 99
吴彦祖 9
上下界:
上界: <:
package Scala3.lession6
class Pair [T <: Comparable[T]]{
def shuai(first: T,second: T): T ={
if (first.compareTo(second) > 0) first else second
}
}
object Test3{
def main(args: Array[String]): Unit = {
val boy1 = new Boy("鹿晗",88)
val boy2 = new Boy("拉尔",99)
val p = new Pair[Boy]
val boy = p.shuai(boy1,boy2)
println(boy.name)
}
}
package Scala3.lession6
class Boy (var name: String,var faceValue: Int) extends Comparable[Boy]{
override def compareTo(o: Boy): Int = {
o.faceValue - this.faceValue
}
}
下界: >:
package Scala3.lession7
class GranderFather
class Father extends GranderFather
class Son extends Father
class Sunzi extends Son
class tongzhuo
object Test {
def getIDCard[R >: Son](person : R): Unit ={
println("身份证交给你保管")
}
def main(args: Array[String]): Unit = {
getIDCard[Son](new Son)
}
}
注意:这个中括号里面,需要谁取就写谁,Sunzi不能取
getIDCard[Son](new Son)
4、视图边界
T <% Person 左侧的类型必须是右侧类型的子类。如果左侧类型不是右侧类型的子类。那么左侧类型会触发隐式转换,转换为右边的类型。
package Scala3.lesion8
class Persion333(var name: String){
def sayHello={
println("你好,我的名字叫"+ name)
}
def makeFriends(p:Persion333): Unit ={
sayHello
p.sayHello
}
}
class Student(name: String) extends Persion333(name)
class Dog(var name: String)
class Worker(var name: String)
class Party[T <% Persion333](p1:Persion333,p2:Persion333){
def play: Unit ={
//人和人交朋友
p1.makeFriends(p2)
}
}
object Test {
def main(args: Array[String]): Unit = {
implicit def dog2person(dog: Dog): Persion333 ={
new Persion333(dog.name)
}
val lisa = new Student("李飒")
val mayun = new Persion333("马云")
val els = new Persion333("二郎神")
val dog = new Dog("哮天犬")
new Party[Persion333](lisa,mayun).play
}
}
5、协变和逆变
协变:
当s 是A的子类, 那么func(s) 是func(A)的子类。 也就是被参数化类型的泛化方向与参数类型的方向是一致的,所以称为协变。
个人理解的func(s) 是func(A)的子类的意思是: func(s)的返回值是func(A)的返回值的子类。
代码实现:
package Scala3.lession9
class QingTong
class BaiJin extends QingTong
class Wangzhe extends BaiJin
class Worker
//支持协变
class Card[+T](val name: String)
object Test {
def wangzhePK(card: Card[QingTong]): Unit ={
println("欢迎来参加英雄联盟大赛")
}
def main(args: Array[String]): Unit = {
val lisa = new Card[QingTong]("李飒")
wangzhePK(lisa)
val hutian = new Card[BaiJin]("胡天")
wangzhePK(hutian)
}
}
逆变:
同协变定义,但是是反过来,即当S是A的子类时,func(S)是func(A)的父类。
代码实现:
package Scala3.lession9
class QingTong
class BaiJin extends QingTong
class Wangzhe extends BaiJin
class Worker
//支持逆变
class Card[-T](val name: String)
object Test {
def wangzhePK(card: Card[QingTong]): Unit ={
println("欢迎来参加英雄联盟大赛")
}
def main(args: Array[String]): Unit = {
val lisa = new Card[QingTong]("李飒")
wangzhePK(lisa)
val hutian = new Card[BaiJin]("胡天")
wangzhePK(hutian)
}
}