scala从入门开始05
- 打包插件优化:
<!--导入scala插件-->
<build>
<pluginManagement>
<plugins>
<!-- 编译scala的插件 -->
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId>
<version>3.2.2</version>
</plugin>
<!-- 编译java的插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId>
<executions>
<execution>
<id>scala-compile-first</id>
<phase>process-resources</phase>
<goals>
<goal>add-source</goal>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>scala-test-compile</id>
<phase>process-test-resources</phase>
<goals>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- 打jar插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>reference.conf</resource>
</transformer>
<!-- 指定maven方法 -->
<!-- <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">-->
<!-- <mainClass>cn._51doit.rpc.Master</mainClass>-->
<!-- </transformer>-->
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
- 执行master,(指定类)
java -cp .AkkaRPC-1.0.jar com._xjk.rpc.Master localhost 8888
1.scala高级部分
- 柯里化方法。先看一个示例:
package com.xjk
object CeliDemo {
// 柯里化
def m1(x:Int)(y:Int): Int = {
x * y
}
def main(args: Array[String]): Unit = {
val r1 = m1(5)(7)
println(r1)// 35
val r2 = m1(4) _
println(r2)// function1
println(r2(4))// 16
}
}
上面m1
函数定义2个参数,当传入一个参数赋值给r2
此时r2
是一个function1
,给r2
传入参数,这样可以执行r2
函数。
- 柯里化结合隐式值
- 柯里化方法结合隐式值,程序在执行时,会在程序编译时,会在程序上下文中查找用implicit修饰的参数类型一致的参数,如果有就优先使用,没有就使用默认值。
package com.xjk
object implicitValueDemo {
def test3(m:Int)(implicit n:Int = 2):Unit = {
println(m * n)
}
def main(args: Array[String]): Unit = {
// test3(5) // 柯里化方法,后面参数用implicit 修饰,可以传入,也可以不传入
implicit val ttt:Int = 100
test3(5)// 500
}
}
- 隐式值
// MyConcetxt.scala
package com.xjk
object MyContext {
implicit val ttt:Int = 100
}
// implicitVaueDemo.scala
package com.xjk
object implicitValueDemo {
def test3(m:Int)(implicit n:Int = 2):Unit = {
println(m * n)
}
def main(args: Array[String]): Unit = {
// 隐式值导入
import MyContext.ttt
test3(5)// 500
}
}
上述是object隐式值导入,如果是class可以通过如下方式导入
// MyConcetxt.scala
package com.xjk
class MyContext {
implicit val ttt:Int = 100
}
// implicitVaueDemo.scala
...
val mc = new MyContext
import mc._
...
- 隐式转换
- 当你执行
1 to 10
会进行隐式转换,将Int
转换为RichInt
- 通过下面代码,查看scala内部系统隐式转换。
- 当你执行
:implicit -v
- RichFile示例:
package com.xjk
import java.io.File
import scala.io.Source
/*
* 使用JavaIO读取数据,File直接使用File的read方法读取文件中的全部内容
* */
class RichFile(val file:File) {
// 包装类扩展方法:自定义read方法
def read():String = {
// 读取所有信息转换字符串
Source.fromFile(file).mkString
}
}
object RichFile {
def main(args: Array[String]): Unit = {
// File是Java原生类,没有read方法。
// 但是可以通过装饰模式扩展一个方法
val file = new File("./test.txt")
// 显式包装:类似RichInt val ri =new scala.runtime.RichInt(1) ri to 10
val richFile = new RichFile(file)
val content = richFile.read()
println(content)
// 隐式包装:上面将Int包装成RichInt再调用to方法没有必要,可以直接调用,因为可以从PreDef中找到一个Int=>RichInt的implicit修饰的方法
// 同样RichFile也可以,添加一个implicit修饰的方法,输入的是File,返回RichFile
import MyPreDef.file2RichFile//导入implicit修饰的方法
val content2: String = file.read()
println(content2)
}
}
implicit修饰方法:
package com.xjk
import java.io.File
object MyPreDef {
// implicit修饰的方法,输入File,返回RichFile
implicit def file2RichFile(f:File):RichFile = new RichFile(f);
// 或者也可以
implicit val fileToRichFile = (f:File) => new RichFile(f)
}
- 上界和下界
package com.xjk
/*
* [T <: Comparable[T]] 上界 不超过最高标准 upper bound java中:<T extends Comparable>
* [T >: Comparable[T]] 下界 不超过最低标准 lower bound java中:<T super Comparable>
* [T % Comparable[T]] 视图界定 view bound
* [T : Comparable] 上下文界定 context bound
* [-T] 逆变 代表方法输入参数
* [+T] 协变 代表方法的返回
* */
class Pair[T <: Comparable[T]] {
def bigger(first:T, secnod:T): T = {
if (first.compareTo(secnod) > 0) first else secnod
}
}
object Pair {
def main(args: Array[String]): Unit = {
val p = new Pair[String]
// string实现comparable接口
val r = p.bigger("Hadoop", "Spark")
println(r)
}
}
- 视图界定
- 使用它需要一个隐式转换的方法或函数。
// 上面代码执行整型比较
val p = new Pair[Int]
val r = p.bigger(1, 6)
// 此时会报错:因为Int没有实现Comparable接口
// 但通过java Integer 不会报错,因为Integer 实现Comparable接口
val p = new Pair[Integer]
val r = p.bigger(1, 6)
当时我通过视图界定,就可以比较了。就存在隐式转换,改成视图界定T <% Comparable[T]]
,将Scala的Int 转换成Java中的Integer
// 源码中implicit定义方法.Scala的Int 转换成Java中的Integer
implicit def int2Integer(x:Int) = java.langInteger.valueOf(x)
- 上下文界定
- 上下文界定,也是结合隐式转换的,需要一个隐式参数
package com.xjk
/*
* [T <: Comparable[T]] 上界 不超过最高标准 upper bound java中:<T extends Comparable>
* [T >: Comparable[T]] 下界 不小于最低标准 lower bound java中:<T super Comparable>
* [T % Comparable[T]] 视图界定 view bound
* [T : Comparable] 上下文界定 context bound
* [-T] 逆变 代表方法输入参数
* [+T] 协变 代表方法的返回
* */
/*
* Ordering 类型 实现Java Comparator接口,对其进行扩展
* Ordered 类型 实现了Java Comparable接口,对其进行扩展
* */
class Pair3[T : Ordering] {
def bigger(first:T, secnod:T): T = {
val ord = implicitly[Ordering[T]]
if (ord.gt(first, secnod)) first else secnod
}
}
// 上下文界定,也是结合隐式转换的,需要一个隐式参数
object Pair3 {
def main(args: Array[String]): Unit = {
// 上下文界定,需要传入一个隐式object(隐式参数)
//
val p = new Pair3[Int]
val r = p.bigger(1,10)
println(r)
}
}
- 示例1:视图界定示例
package com.xjk
class Pair2[T <% Ordered[T]] {
def bigger(first:T, secnod:T): T = {
if (first.compareTo(secnod) > 0) first else secnod
}
}
object Pair2 {
def main(args: Array[String]): Unit = {
import MyPreDef.boy2OrderedBoy//导入隐式转换方法
val p = new Pair2[Boy]
val b = p.bigger(new Boy("liu", 20, "swim"), new Boy("wang", 25, "pingpang"))
print(b.name)
}
}
// 隐式转换方法,函数实现
package com.xjk
import java.io.File
object MyPreDef {
// 传入隐式转换方法
implicit def boy2OrderedBoy(b:Boy): Ordered[Boy] = new Ordered[Boy] {
override def compare(that: Boy): Int = {
b.age - that.age
}
}
// 传入隐式转换函数
implicit def boyToOrderBoy = (b:Boy) => new Ordered[Boy] {
override def compare(that: Boy): Int = {
b.age - that.age
}
}
}
- 示例2:上下文界定示例
implicit object BoyToOrderingBoy extends Ordering[Boy] {
override def compare(x: Boy, y: Boy): Int = {
x.age - y.age
}
}
- 柯里化方式实现隐式转化
package com.xjk
/*
* 不使用上下文界定,也不使用视图界定,但要实现隐式转换
* */
class MrRight[T] {
// 柯里化结合隐式转换,实现类似于视图界定的功能
def choose(first:T, second:T)(implicit t:T => Ordered[T]): T = {
if (first > second) first else second
}
// 柯里化结合隐式转换,实现类似于上下文界定的功能
def select(first:T, second:T)(implicit ord: Ordering[T]): T = {
if (ord.gt(first,second)) first else second
}
}
object MrRight {
def main(args: Array[String]): Unit = {
import MyPreDef._
val mr = new MrRight[Boy]
val b = mr.choose(new Boy("liu", 20, "swim"), new Boy("wang", 25, "pingpang"))
println(b.name)
}
}
scala-adv