文档章节

隐式转换

blue1110
 blue1110
发布于 2015/02/12 18:23
字数 719
阅读 21
收藏 0

1:隐式转换应用

1.1 隐式转换为期望类型

    隐式转换为期望类型是编译器会使用隐式操作的第一个地方。一旦编译器看到了X,但是需要Y,就会检查从X到Y的隐式转换函数。例如:

val i : Int = 3.5
<console>:10: error: type mismatch;
 found   : Double(3.5)
 required: Int
       val i : Int = 3.5

然而,可以通过定义隐式转换消除这个问题:

implicit def doubleToInt(x: Double) = x.toInt
scala> val i : Int = 3.5
i: Int = 3

 过程如下:编译器看到了3.5 Double,但是它需要Int(此处导致类型错误),但是它搜索了从Double到Int的隐式转换,发现 doubleToInt(因为doubleToInt可以当作单一标示符处于作用域当中),实际上,代码后来变成:

val i : Int = doubleToInt(3.5)

1.2 转换接收者

   隐式转换同样还应用于方法调用的接收者,也就是方法调用的对象。

 a:与新类型的交互操作

    接收者转换的主要用途之一是使得新类型更为平滑地集成到现存类型当中。例如,如下有个例子:

Rational 类的片段

class Rational(n:Int,d:Int){
...
def + (that:Rational):Rational = ...
def + (that:Int):Rational = ...
...
}

Rational类有两个重载的+号方法变体,分别带 Rational 以及Int为参数。可以做有理数之间的加法,以及有理数加上整数:

val oneHalf = new Rational(1,2)
oneHalf + oneHalf
oneHalf + 1

但是:1 + oneHalf 却有问题,因为Int并没有合适的加有理数的方法。

此处,我们可以定义从Int到Rational的隐式转换:

implicit def intToRational(x:Int) = new Rational(x,1)

    b:模拟新的语法

    隐式转换的另一种主要用途是模拟添加新的语法。

比如: Map(1-> "one",2->"two")

而 -> 只是定义在标准scala序文(scala.predef)中的类 ArrowAssoc的方法。这个序文还定义了从Any到ArrowAssoc的隐式转换。在 1-> "one" 的时候,编译器会插入从1到ArrowAssoc的转换以便找到 ->方法。以下是相关的定义:

package scala
object Predef{
    class ArrowAssoc[A](x:A){
        def -> [B](y:B):Tuple2[A,B] = Tuple2(x,y) 
    }
    implicit def any2ArrowAssoc[A](x:A):ArrowAssoc[A]=
        new ArrowAssoc(x)
        ....
}


2.隐式转换规则

 a.标记规则:只有标记为implicit才能可用

 b.做用户规则:插入的隐式转换必须以单一标识符的形式处于作用域中,或者跟转换的源或目标类型关联在一起。

例外只有一个:编译器还会在源类型活着转换的期望目标类型的伴生对象中寻找隐事定义。例如:

object Dollar{
 implicit def dollarToEuro(x:Dollar):Euro = ...
}
class Dollar{
}

c.无歧义规则:不存在其他可插入的转换

d:单一调用规则:只会尝试一个隐事操作

e:显式操作先行


PS:文章整理自 Programming in scala

© 著作权归作者所有

共有 人打赏支持
blue1110
粉丝 8
博文 13
码字总数 7360
作品 0
南京
程序员
scala implicit 关键字

implicit 可分为: 隐式参数 隐式转换类型 隐式调用函数 1.隐式参数 当我们在定义方法时,可以把最后一个参数列表标记为implicit,表示该组参数是隐式参数。一个方法只会有一个隐式参数列表,...

张欢19933
04/27
0
0
对Scala隐式转换的一些总结

以下讨论基于Scala 2.7/2.8 Scala提供的隐式转换特性可以在效果上给一个类增加一些方法,或者用于接收不同类型的对象,然而使用Scala的隐式转换是有一定的限制的,总结如下 implicit关键字只...

ggd543archer
07/28
0
0
Scala Implicit Conversion

Scala Implicit Conversion 从一个简单例子出发,我们定义一个函数接受一个字符串参数,并进行输出 def func(msg: String): Unit = println(msg) 这个函数在func("11")调用时候正常,但是在执行...

秋风醉了
2015/04/28
0
0
《CLR Via C# 第3版》笔记之(八) - 类型的转换构造器和方法

主要内容 类型的转换构造器 显式/隐式的转换操作符 1. 类型的转换构造器 类型转换构造器是指 通过一种类型(比如Type1)的实例来构造另一种类型(比如Type2)的实例。 一般用于: 1) Type1和...

zting科技
2017/10/17
0
0
c++ explicit 修饰符

按照默认规定,只有一个参数的构造函数也定义了一个隐式转换,将该构造函数对应数据类型的数据转换为该类对象,如下面所示: class String { String ( const char* p ); // 用C风格的字符串p...

liangtee
2013/05/01
0
6

没有更多内容

加载失败,请刷新页面

加载更多

用户体验要素——以用户为设计中心

一、用户体验是什么 产品会与外界发生联系,人们如何去使用产品,人们使用产品无非解决两种问题,一,提高效率;二娱乐。而用户体验兼顾着功能和界面两个方面,为的是“提高人们的工作效率”...

铸剑为犁413
39分钟前
0
0
学习设计模式——代理模式

1. 认识代理模式 1. 定义:为其他对象提供一种代理以控制对这个对象的访问。 2. 组织结构: Proxy:代理对象,要实现与目标代理对象的相同的接口,这样就可以使用代理来代替具体的目标对象,...

江左煤郎
今天
1
0
java JDK动态代理

本篇随笔是对java动态代理中的JDK代理方式的具体实现。 首先需要定义一个接口,为其定义了两个方法:   public interface UserService { public void add(); public void delete(); } 然后需...

编程SHA
今天
2
0
轻松理解Dubbo分布式服务框架

Dubbo是什么? Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。简单的说,dubbo就是个服务框架,如果没有分布式的需求,其实是不需要用的...

别打我会飞
今天
2
0
TypeScript基础入门之JSX(一)

转发 TypeScript基础入门之JSX(一) 介绍 JSX是一种可嵌入的类似XML的语法。 它旨在转换为有效的JavaScript,尽管该转换的语义是特定于实现的。 JSX在React框架中越来越受欢迎,但此后也看到了...

durban
今天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部