Fork me on GitHub

scala快速入门05

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

posted @ 2021-02-18 19:20  是阿凯啊  阅读(55)  评论(0编辑  收藏  举报