为 scala generic 提供默认类型值
Provide default type value for scala generic
我正在尝试使用 scala 类型 classes 并遇到以下问题。我用多种方法创建了一个 class。每个方法都有一个隐式参数 B 和 returns 一个 Either[A,B] .
Type B 是一个转换器,调用者可以在其中提供自定义对象以按照他需要的方式包装响应。
所以这是代码
case class A( var value:String){
}
case class Converter[A]( value : (Map[String, String] ) => A )
object Converter{
implicit val AConverter = new Converter[A]( (x:Map[String, String]) => new A("Hello World") )
implicit val IntConverter = new Converter[Int]( (x:Map[String, String]) => 10 )
}
class API{
def method1[B : Converter] : Either[A, B] = {
Right( implicitly[Converter[B]].value(Map.empty))
}
def method2[B : Converter](name:String) : Either[A, B] = {
Right( implicitly[Converter[B]].value(Map.empty))
}
def method3[B : Converter](id:Int) : Either[A, B] = {
Right( implicitly[Converter[B]].value(Map.empty))
}
}
现在我的麻烦来了。我想获得关注
Each method should be callable without worring about the implicit param B because there should be a default implementation somewhere be defined.
所以我在伴随对象中定义了一些隐式,但这根本没有解决我的问题!
// Works due implicit definiton
println( new API().method1[A])
// Works due implicit definiton
println( new API().method1[Int])
// Works not but should
println( new API().method1)
我想说方法1的B的类型是Converter[A],B的类型 对于 method2 是 Converter[Int] 如果调用者不提供它。
// Implementation should use my default Converter[A]
println( new API().method1)
我在这里遇到了这个问题
那么,如果类型本身根本没有像示例中那样传递给方法,我该如何提供默认类型。我需要每个方法而不是 class.
嗯,这可能不完全是问题的答案,而是针对您的问题的解决方案。
如果你想调用 new API().method1
那么,与其寻找指定默认类型参数的方法,不如定义一个没有类型参数的函数 method1
?
case class A( var value:String){
}
case class Converter[A]( value : (Map[String, String] ) => A )
object Converter{
implicit val AConverter = new Converter[A]( (x:Map[String, String]) => new A("Hello World") )
implicit val IntConverter = new Converter[Int]( (x:Map[String, String]) => 10 )
}
class API{
def method1: Either[A, A] = {
Right(Converter.AConverter.value(Map.empty))
}
def method1[B : Converter] : Either[A, B] = {
Right( implicitly[Converter[B]].value(Map.empty))
}
def method2[B : Converter](name:String) : Either[A, B] = {
Right( implicitly[Converter[B]].value(Map.empty))
}
def method3[B : Converter](id:Int) : Either[A, B] = {
Right( implicitly[Converter[B]].value(Map.empty))
}
}
val undefined = new API().method1
val defined = new API().method1[Int]
这应该可以调用 new API().method1
。但是,也有局限性。例如。类型推断可能不会像人们预期的那样工作:
val defined: Either[A, Int] = new API().method1
不编译。
我和你的想法一样,最终找到了这个解决方案。它有点开销,但它似乎按照我需要的方式工作!
class A( val value:String){
val success = true;
}
class B( value:String) extends A(value){
override val success = false;
}
class C( override val value:String = "Doo") extends A(value){
override val success = false;
}
case class Converter[A]( value : (Map[String, String] ) => A ){
}
object Converter{
implicit lazy val method1Converter = new Converter[B]( (x:Map[String, String]) => new B("foo") )
implicit lazy val method2Converter = new Converter[C]( (x:Map[String, String]) => new C() )
}
trait method1Impl{
def method1 : Either[A, B] = {
Right( Converter.method1Converter.value( Map.empty ) )
}
def method1[B : Converter] : Either[A, B] = {
Right( implicitly[Converter[B]].value(Map.empty))
}
}
trait method2Impl{
def method2 : Either[A, C] = {
Right( Converter.method2Converter.value( Map.empty ) )
}
def method2[B : Converter]( name:String) : Either[A, B] = {
Right( implicitly[Converter[B]].value(Map.empty))
}
}
class API extends method1Impl with method2Impl {
}
// Works not but should
println( new API().method1)
println( new API().method2[C]("Hello"))
我正在尝试使用 scala 类型 classes 并遇到以下问题。我用多种方法创建了一个 class。每个方法都有一个隐式参数 B 和 returns 一个 Either[A,B] .
Type B 是一个转换器,调用者可以在其中提供自定义对象以按照他需要的方式包装响应。
所以这是代码
case class A( var value:String){
}
case class Converter[A]( value : (Map[String, String] ) => A )
object Converter{
implicit val AConverter = new Converter[A]( (x:Map[String, String]) => new A("Hello World") )
implicit val IntConverter = new Converter[Int]( (x:Map[String, String]) => 10 )
}
class API{
def method1[B : Converter] : Either[A, B] = {
Right( implicitly[Converter[B]].value(Map.empty))
}
def method2[B : Converter](name:String) : Either[A, B] = {
Right( implicitly[Converter[B]].value(Map.empty))
}
def method3[B : Converter](id:Int) : Either[A, B] = {
Right( implicitly[Converter[B]].value(Map.empty))
}
}
现在我的麻烦来了。我想获得关注
Each method should be callable without worring about the implicit param B because there should be a default implementation somewhere be defined.
所以我在伴随对象中定义了一些隐式,但这根本没有解决我的问题!
// Works due implicit definiton
println( new API().method1[A])
// Works due implicit definiton
println( new API().method1[Int])
// Works not but should
println( new API().method1)
我想说方法1的B的类型是Converter[A],B的类型 对于 method2 是 Converter[Int] 如果调用者不提供它。
// Implementation should use my default Converter[A]
println( new API().method1)
我在这里遇到了这个问题
那么,如果类型本身根本没有像示例中那样传递给方法,我该如何提供默认类型。我需要每个方法而不是 class.
嗯,这可能不完全是问题的答案,而是针对您的问题的解决方案。
如果你想调用 new API().method1
那么,与其寻找指定默认类型参数的方法,不如定义一个没有类型参数的函数 method1
?
case class A( var value:String){
}
case class Converter[A]( value : (Map[String, String] ) => A )
object Converter{
implicit val AConverter = new Converter[A]( (x:Map[String, String]) => new A("Hello World") )
implicit val IntConverter = new Converter[Int]( (x:Map[String, String]) => 10 )
}
class API{
def method1: Either[A, A] = {
Right(Converter.AConverter.value(Map.empty))
}
def method1[B : Converter] : Either[A, B] = {
Right( implicitly[Converter[B]].value(Map.empty))
}
def method2[B : Converter](name:String) : Either[A, B] = {
Right( implicitly[Converter[B]].value(Map.empty))
}
def method3[B : Converter](id:Int) : Either[A, B] = {
Right( implicitly[Converter[B]].value(Map.empty))
}
}
val undefined = new API().method1
val defined = new API().method1[Int]
这应该可以调用 new API().method1
。但是,也有局限性。例如。类型推断可能不会像人们预期的那样工作:
val defined: Either[A, Int] = new API().method1
不编译。
我和你的想法一样,最终找到了这个解决方案。它有点开销,但它似乎按照我需要的方式工作!
class A( val value:String){
val success = true;
}
class B( value:String) extends A(value){
override val success = false;
}
class C( override val value:String = "Doo") extends A(value){
override val success = false;
}
case class Converter[A]( value : (Map[String, String] ) => A ){
}
object Converter{
implicit lazy val method1Converter = new Converter[B]( (x:Map[String, String]) => new B("foo") )
implicit lazy val method2Converter = new Converter[C]( (x:Map[String, String]) => new C() )
}
trait method1Impl{
def method1 : Either[A, B] = {
Right( Converter.method1Converter.value( Map.empty ) )
}
def method1[B : Converter] : Either[A, B] = {
Right( implicitly[Converter[B]].value(Map.empty))
}
}
trait method2Impl{
def method2 : Either[A, C] = {
Right( Converter.method2Converter.value( Map.empty ) )
}
def method2[B : Converter]( name:String) : Either[A, B] = {
Right( implicitly[Converter[B]].value(Map.empty))
}
}
class API extends method1Impl with method2Impl {
}
// Works not but should
println( new API().method1)
println( new API().method2[C]("Hello"))