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)
我想A
是String
,当编译器没有关于来推断哪种类型的提示.所以我可以重载我的定义:
def apply( id: String )( implicit processor: Processor[String] ) =
processor( data get id )
Run Code Online (Sandbox Code Playgroud)
但是这两种方法在擦除后都会有相同的签名...有没有办法提供默认类型?
您可以通过定义以下幻像类型来实现此目的:
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)