方法调用的默认类型

par*_*tic 4 generics types scala type-parameter

我想知道在Scala中调用类型参数化方法时是否可以使用默认类型.假设我在某处有以下方法:

def apply[A]( id: String )( implicit processor: Processor[A] ) =
  processor( data get id )
Run Code Online (Sandbox Code Playgroud)

我想AString,当编译器没有关于来推断哪种类型的提示.所以我可以重载我的定义:

def apply( id: String )( implicit processor: Processor[String] ) =
  processor( data get id )
Run Code Online (Sandbox Code Playgroud)

但是这两种方法在擦除后都会有相同的签名...有没有办法提供默认类型?

Aar*_*rup 7

您可以通过定义以下幻像类型来实现此目的:

sealed class DefaultsTo[A, B]
trait LowPriorityDefaultsTo {
   implicit def overrideDefault[A,B] = new DefaultsTo[A,B]
}
object DefaultsTo extends LowPriorityDefaultsTo {
   implicit def default[B] = new DefaultsTo[B, B]
}
Run Code Online (Sandbox Code Playgroud)

然后你的方法可以编写

def apply[A]( id: String )( implicit e: A DefaultsTo String,
                                     processor: Processor[A] ) =
   processor( data get id )
Run Code Online (Sandbox Code Playgroud)

overrideDefault对于任何两种指定类型的保证的定义,A以及B编译器总是可以提供类型的对象DefaultsTo[A, B](例如DefaultsTo[Int, String]).但是,如果两种类型中的一种未指定(例如DefaultsTo[A, String]),编译器将更喜欢识别这两种类型(在示例中提供,DefaultsTo[String, String]因此推断String出未指定的类型A).

正如Naftoli Gugenheim在这个邮件列表线程中指出的那样,你也可以使用一些很好的语法来使用上下文边界:

class Has[B] {
   type AsDefault[A] = A DefaultsTo B
}

def apply[A : Has[String]#AsDefault : Processor](id: String) =
   implicitly[Processor[A]].apply(data get id)
Run Code Online (Sandbox Code Playgroud)