分享

学习scala的那五天__第五天

ABCDer丶Bi 发表于 2017-10-23 19:33:56 [显示全部楼层] 回帖奖励 阅读模式 关闭右栏 0 4996
本帖最后由 ABCDer丶Bi 于 2017-10-23 19:36 编辑

5.高阶函数

5.1 概念
Scala混合了面向对象和函数式的特性,我们通常将可以做为参数传递到方法中的表达式叫做函数。在函数式编程语言中,函数是“头等公民”,高阶函数包含:作为值的函数、匿名函数、闭包、柯里化等等。
5.2 作为值的函数
可以像任何其他数据类型一样被传递和操作的函数,每当你想要给算法传入具体动作时这个特性就会变得非常有用。
[mw_shl_code=scala,true]
val arr =Array(1,2,3,4,5)
//定义一个函数并将函数赋给变量fun1
fun1=(x:Int)=>x*2
//将函数作为参数传入map方法中
arr.map(fun1)
[/mw_shl_code]
定义函数时格式:val 变量名 = (输入参数类型和个数) => 函数实现和返回值类型和个数
“=”表示将函数赋给一个变量
“=>”左面表示输入参数名称、类型和个数,右边表示函数的实现和返回值类型和参数个数
5.3 匿名函数
Scala中,你不需要给每一个函数命名,没有将函数赋给变量的函数叫做匿名函数
[mw_shl_code=scala,true]
//直接将匿名函数传入到map方法中,效果和前面一样,比较精简一些
arr.map((x:Int)=>x*2)
//由于Scala可以自动推断出参数的类型,所有可以写的跟精简一些
arr.map(x=>x*2)
//还记得神奇的下划线吗?这才是究极方式
arr.map(_*2)//最喜欢的神奇下划线
[/mw_shl_code]
5.4 将方法转换成函数
Scala中,方法和函数是不一样的,最本质的区别是函数可以做为参数传递到方法中
但是方法可以被转换成函数,神奇的下划线又出场了
[mw_shl_code=scala,true]
//定义一个方法
def m(x:Int)=x*3
//神奇的下划线将方法转换成了函数
val fun2=m_
//将函数传入map方法中
arr.map(fun2)
[/mw_shl_code]
5.5 柯里化
柯里化指的是将原来接受两个参数的方法或函数变成新的接受一个参数的方法或函数的过程
[mw_shl_code=scala,true]
//一个比较奇怪的方法,看起来即像方法又像函数
def m(x:Int)=(y:Int)=>x*y
//将一个参数2传进函数后,彻底变成了一个函数
val func=m(2)  //val func = (x:Int)=>2*y
//然后再调用这个函数并传递第二个参数,得到最终结果
func(3)
//在Scala中这样的函数可以简写成
m(2)(3)  //def m(x:Int)(y:Int)=x*y
[/mw_shl_code]
5.6 栗子[mw_shl_code=scala,true]
object FunDemo {
  def main(args: Array[String]) {
    def f2(x: Int) = x * 2
    val f3 = (x: Int) => x * 3
    val f4: (Int) => Int = { x => x * 4 }
    val f4a: (Int) => Int = _ * 4
    val f5 = (_: Int) * 5
    val list = List(1, 2, 3, 4, 5)
    var new_list: List[Int] = null
    //第一种:最直观的方式 (Int) => Int
    //new_list = list.map((x: Int) => x * 3)

    //第二种:由于map方法知道你会传入一个类型为(Int) => Int的函数,你可以简写
    //new_list = list.map((x) => x * 3)

    //第三种:对于只有一个参数的函数,你可以省去参数外围的()
    //new_list = list.map(x => x * 3)

    //第四种:(终极方式)如果参数在=>右侧只出现一次,可以使用_
    new_list = list.map(_ * 3)

    new_list.foreach(println(_))

    var a = Array(1,2,3)
    a.map(_* 3)
  }
}
[/mw_shl_code]
6.隐式转换和隐式参数
6.1 概念
隐式转换和隐式参数是Scala中两个非常强大的功能,利用隐式转换和隐式参数,你可以提供优雅的类库,对类库的使用者隐匿掉那些枯燥乏味的细节。
6.2 作用
隐式的对类的方法进行增强,丰富现有类库的功能
6.3 隐式转换函数
是指那种以implicit关键字声明的带有单个参数的函数
6.4 隐式转换例子
[mw_shl_code=scala,true]
import java.io.File
import scala.io.Source

//隐式的增强File类的方法
class RichFile(val from: File) {
  def read = Source.fromFile(from.getPath).mkString
}

object RichFile {
  //隐式转换方法
  implicit def file2RichFile(from: File) = new RichFile(from)
}

object MainApp{
  def main(args: Array[String]): Unit = {
    //导入隐式转换
    import RichFile._
    //import RichFile.file2RichFile
    println(new File("c://words.txt").read)
  }
}
[/mw_shl_code]

[mw_shl_code=scala,true]
import java.awt.GridLayout

object ImplicitContext{
  //implicit def girl2Ordered(g : Girl) = new Ordered[Girl]{
  //  override def compare(that: Girl): Int = if (g.faceValue > that.faceValue) 1 else -1
  //}

  implicit object OrderingGirl extends Ordering[Girl]{
    override def compare(x: Girl, y: Girl): Int = if (x.faceValue > y.faceValue) 1 else -1
  }
}

class Girl(var name: String, var faceValue: Double){
  override def toString: String = s"name : $name, faveValue : $faceValue"
}

//class MissRight[T <% Ordered[T]](f: T, s: T){
//  def choose() = if(f > s) f else s
//}
//class MissRight[T](f: T, s: T){
//  def choose()(implicit ord: T => Ordered[T]) = if (f > s) f else s
//}

class MissRight[T: Ordering](val f: T, val s: T){
  def choose()(implicit ord: Ordering[T]) = if(ord.gt(f, s)) f else s
}

object MissRight {
  def main(args: Array[String]) {
    import ImplicitContext.OrderingGirl
    val g1 = new Girl("yuihatano", 99)
    val g2 = new Girl("jzmb", 98)
    val mr = new MissRight(g1, g2)
    val result = mr.choose()
    println(result)
  }
[/mw_shl_code]




没找到任何评论,期待你打破沉寂

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条