2017-02-01 25 views
0

对于错误的标题感到抱歉。
我正在使用具有此特征的基础特征和多个实现的库。然而,取代传统的方法重写,方法专用化是通过采用隐式参数的方法提供的。一般模式是如下在运行时得到最精确的隐含关系

class Cont[TT](val n : Int) 

trait I[ +Self ] { 
    final def foo[TT >: Self](implicit num : Cont[TT]) = num.n 
} 

trait B extends I[B] 

object B { 
    implicit def Mint : Cont[B] = new Cont[B](53) 
} 

class S extends B with I[S] 

object S{ 
    implicit def HMint : Cont[S] = new Cont[S](54) 
} 

B是“基本类型”,其中,你将有几个亚类(其中S是一个例子)。这个子类中的每一个都会提供一些implicits(就像我们在例子中为Cont所做的那样),对于每个想要专门化的方法来说都有一个。如果未定义某个隐式,则使用B中的一个(上面的代码中未显示)。你实际上想要在B及其子类上调用的方法在特质I中定义,每种方法都有一种类型。
我的问题是,我想写泛型函数作为参数B或其子类的集合,并调用它们的方法,但我想要调用最具体的含义。 问题是,与重写方法不同,“编译时”类型定义了将调用哪个方法。例如:

val s = new S 
val b : B = s 
(b.foo,s.foo) 
res50: (Int, Int) = (53,54) 

我可以写我这样普通的功能,最具体的方法将被调用?如果没有,图书馆是否会发生一些轻微变化?最后,这个图书馆使用的模式是否有名字?很难找到关于名字不知道的模式的信息。

回答

1

您可以编写将基类型作为传递参数的泛型函数,但如果您需要该类型的成员方法,则必须确定派生类型。

def f(b:B) = b match { 
    case s:S => s.foo 
    case _ => b.foo 
} 
f(new S) // res0: Int = 54 

P.S.唉,我不知道这个模式是否有名字。