Scala重载解析

如果一个标识符或选择e引用了数个类的成员,则将使用引用的上下文来推断唯一的成员。使用的方法将依赖于e是否被用作一个函数。设A是e引用的成员的集合。
首先假定e作为函数出现在应用中,比如e(args)。如果在A中有且仅有一个可选成员是一个(可能是多态)方法类型,其元数与给出的参量数目匹配,则就会选定该可选成员。
否则,设Ts是通过用未定义类型来类型化每个参量所得到的类型向量。首先要确定的是可用的可选成员的集合。如果Ts中每个类型都与对应的可选成员中正式参数类型相似,且如果期望类型已定义,方法的结果类型与之兼容,则该可选项是可用的。对于一个多态方法,如果本地类型推断可以确定类型参量,则该实例化的方法是可用的,继而该多态方法也是可用的。
设B是可用的可选项的集合。如果B为空则导致错误。否则可以用以下”同样具体”和”更具体” 的定义来选出在B中最具体的可选项:
具有类型(Ts)U的参数化的方法,如果有某些类型为S的其他成员,S对于类型Ts的参量(ps)是可用的,则该方法与这些成员同样具体。
具有类型[a1 >: L1 <: U1,...,an >: Ln <: Un]T的多态方法,如果有某些类型为S其他成员,如果假定对于i=1,...,n,每个ai都是一个抽象类型命名,其边界在Li之上且在Ui之下,有T和S同样具体,则该方法和这些成员同样具体。
具有其他类型的成员总是与一个参数化的方法或一个多态方法同样具体。
给定具有类型T和U的两个没有参数化也不是多态方法类型的成员,类型为T的成员与类型为U的成员同样具体的条件是T的双重存在与U的双重存在相似。这里多态类型[a1 >: L1 <: U1,...,an >: Ln <: Un]T的双重存在是T forSome { type a1 >: L1 <: U1,...,type an >: Ln <: Un}。其他类型的双重存在是类型自身。
如果A与B同样具体,同时要么B与A不同样具体,要么A在B的一个子类中定义,则A比B更具体。
如果B中没有可选项比B中其他可选项更具体则将导致错误。
下面假定e以函数的形式在类型应用中出现,比如e[targs]。那么我们将选择A中所有的与targs中的类型参量具有同样数目的参数类型的可选项。如果没有该类可选项将导致错误。如果有多个这样的可选项,则将对整个表达式e[targs]重新应用重载解析。
最后我们假定e没有在应用或类型应用中做为函数出现。如果给出了期望类型,设B是A中与其兼的该类可选项的集合。否则,设B为A。在此情况下我们在B的所有可选项中选择最具体的可选项。如果B中没有可选项比B中其他所有的可选项更具体则将导致错误。
在所有情况下,如果最具体的可选项定义在类C中,且有另外一个可应用的可选项定义在C的子类中,则将导致错误。
示例6.25.1 考虑以下定义:
class A extends B {}
def f(x: B, y: B) = ...
def f(x: A, y: B) = ...
val a: A
val b: B
则应用f(b, b)指向f的第一个定义,应用f(a, a)指向第二个。假设我们添加第三个重载定义
def f(x: B, y: A) = ...
则应用f(a, a)将因模糊定义而被拒绝,因为不存在更具体的可应用签名。

更多精彩内容请关注:http://bbs.superwu.cn

关注超人学院微信二维码:

关注超人学院java免费学习交流群:

时间: 2024-11-03 03:39:46

Scala重载解析的相关文章

scala语法解析(解码指环)

看惯了JAVA的语法,再看scala的语法,有的晦涩难懂.正好遇到一个介绍scala语法的文章,就直接截图留念.省的再临时抱佛脚了. scala语法解析(解码指环)

Scala归并排序解析

一.源代码 def msort[T](xs:List[T])(lt: (T,T) => Boolen):List[T]={ val n = xs.length / 2 if ( n == 0 ) xs else{ def merge(xs: List[T],ys: List[T]):List[T] = (xs, ys) match{ case(Nil, ys) => ys case(xs, Nil) => xs case(x:: xs1,y:: ys1)=> if(lt(x,y))

Scala隐含参数详解

隐含参数隐含参数列表(implicit p1,...,pn)将参数p1,...,pn标记为隐含的.一个方法或构造器仅能有一个隐含参数列表,且必须是给出的参数列表的最后一个.具有隐含参数列表的方法可以像正常方法一样应用到参量上.这种情况下implicit标识符没有作用.然而如果该方法没有隐含参数列表中的参量,对应的参量会自动提供.有两种情况实体参量可以传递给类型为T隐含参数.首先,所有的标识符x可以在方法被调用的地方无需前缀就可以访问到,且该标识符表示一个隐含定义(§7.1)或隐含参数.一个可用的

Scala视图

视图隐含参数和方法也可以定义隐式转换,称作视图.由类型S到类型T的视图由一个函数类型为S=>T或(=>S)=>T的隐含值或一个可以转变为该类型的值定义.视图在两种情况下应用.1. 如果表达式e类型为T,且T与表达式的期望类型不一致.这种情况下将会搜索一个隐含的v,v可以应用到e且结果类型与pt一致.搜索的形式类似于隐含参数,隐含作用域类似于T => pt.如果找到了这样一个视图,则表达式e变为v(e).2. 选择e.m中,e的类型为T,如果选择器m并不表示T的成员.这种情况下会搜索

C++操作符重载(Boolan)

C++中操作符号重载重要通过成员函数很全局函数来实现,为了实现对成员数据的访问通常将全局函数声明为友元.重载的函数名称使用operator关键字,如operator op(),op可以是常见的+.-.*./等操作号,也可以自定义转换函数如:operator int(),定义了对象转换成int的方式. 重载函数的调用方式,如a+b,a为类对象,若实现了+重载,将调用a.operator+(b),在这里+运算符作用于左边的对象,例如: std::string str = "Hello, "

大数据系列修炼-Scala课程06

关于Scala中的正则表达式与模式匹配结合的正则表达式Reg 正则表达式的实现:正则表达式的定义与其它语言差不多,只需在表达式后加一个.r,并且可以遍历相应的表达式进行匹配 //定义的正则表达式 val regex="""([0-9]+) ([a-z]+)""".r //由数字与字母组成的常量 val numPattern = "[0-9]+".r //由数字组成的常量 val numberPattern = "&q

【java解惑】重载构造函数

如下所示代码: public class Example046 { private Example046(Object o) { System.out.println("Object"); } private Example046(double[] dArray) {//2 System.out.println("double array"); } private Example046(String str) {//3 System.out.println(&quo

template_12特化与重载

1,重载函数模板f<int*>((int*)pi);//1f<int>((int*)pi);//2上面用int*替换第一个模板的T,用int来替换第二个模板的T.那么将得到两个相同参数类型(int*)的同名函数.也就是不仅同名模板可以同时存在,它们各自具有相同参数类型和返回类型的实例化体也可以同时存在. f(pi);对于这两个模板实参演绎都可以获得成功,即f<int*>(int*)和f<int>(int*).这也就意味着调用是二义性的.但是,考虑重载解析的额

C++的函数重载(转)

函数重载的重要性不言而明,但是你知道C++中函数重载是如何实现的呢(虽然本文谈的是C++中函数重载的实现,但我想其它语言也是类似的)?这个可以分解为下面两个问题 1.声明/定义重载函数时,是如何解决命名冲突的?(抛开函数重载不谈,using就是一种解决命名冲突的方法,解决命名冲突还有很多其它的方法,这里就不论述了) 2.当我们调用一个重载的函数时,又是如何去解析的?(即怎么知道调用的是哪个函数呢) 这两个问题是任何支持函数重载的语言都必须要解决的问题!带着这两个问题,我们开始本文的探讨.本文的主