scala-隐式转换

例子一:

implicit def stringWrapper(s : String) =
    new RandomAccessSeq[Char] {
      def length = s.length
      def apply(i : Int) = s.charAt(i)
    }

这是一个String=>RandomAccessSeq的隐式转换,只要import这个隐式转换,String会被编译器替换为RandomAccessSeq

例子二:

implicit def int2String(x : Int) = x.toString

一个Int=>String的隐式转换,import后,Int会被编译器替换为String

例子三:

implicit def double2Int(x : Double) = x.toInt

一个Double=>Int的隐式转换,import后,Double会被编译器转换为Int

例子四:

implicit def int2Double(x : Int) = x.toDouble

一个Int=>Double的隐式转换,import后,Int会被编译器转换为Double


例子一到例子四的implicit,看上去像是一个宏定义,只不过比宏定义更加的聪明。当编译器碰到了String、Int、Double时,会自动的将它们根据隐式转换的规则进行转换。


例子五:隐式参数

class PreferredDrink(name : String){}

implicit val prompt = new PreferredPrompt("Yes, master")

def greet(name : String)(implicit prompt : PreferredDrink) = {
    println("yes")
  }

在调用greet时,只需要传入第一个参数即可,因为隐式参数就像是宏定义,取代了greet的第二个参数


例子六:带有隐式参数的函数

def maxList[T](elements : List[T])
                (implicit orderer : T => Ordered[T]) : T =
    elements match {
      case List() =>
        throw new IllegalArgumentException("empty list")
      case List(x) => x
      case x :: rest =>
        val maxRest = maxList(rest) //maxList有两个参数的,第二个参数编译器用隐式值补足
        if (x > maxRest) x                     //x不一定有>的方法,如果没有,编译器自动隐式转换为orderer(x)
        else maxRest
    }

隐式参数orderer,类型是T=>Ordered[T],提供了更多的T类型的信息,类型T由List[T]指明,如果存在T=>Ordered[T]的隐式转换,则是有效的。

orderer是相当关键的参数信息,就是为了说明T具体是什么样的,并不是随便一个类型可以满足T=>Ordered[T]的类型。

如果将implicit用于参数上,编译器不仅将会尝试用隐式值补足参数,还会把这个参数当做可用的隐式操作而用于方法体中。


例子六中的隐式参数使用方法非常的普遍,可以用“视界”来简化maxList:

def maxList[T <% Ordered[T]](elements : List[T]) : T,后面的方法是一样的。

注意,这里是<%(视界),而不是<:(上界),觉得“视界”比“上界”多了一个隐式转换。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值