Scala 带反射的泛型参数的改进

Scala 带反射的泛型参数的改进,scala,generics,reflection,Scala,Generics,Reflection,下面是我目前正在处理的Http客户端的简化: class Request[A]( val url: String, val event: Callbacks[A] ) { def run: Try[A] = ... } case class Image( override val url: String, override val event: Callbacks[Bitmap] ) extends Request[Bitmap] 我希望改进我的API,使GET调用如下: GET[I

下面是我目前正在处理的Http客户端的简化:

class Request[A]( val url: String, val event: Callbacks[A] )
{
    def run: Try[A] = ...
}
case class Image( override val url: String, override val event: Callbacks[Bitmap] ) extends Request[Bitmap]

我希望改进我的API,使
GET
调用如下:

GET[Image]( "http://...", null )
object GET {
  def apply[C <: Content](url: String, event: Callbacks[C])
                         (implicit rb: RequestBuilder[C]): C = {
    rb.create(url, event).run
  }
}

object HttpClient extends App {
  import ImplicitContainer._

  val bitmap = GET[Bitmap]("http://...", null)
  println(bitmap)
}

提供泛型参数
Image
应该意味着我正在使用
位图
,因此我不想再次指定它。

我能得到的最接近的方法是提供一个隐式参数,并将所有结果映射器(图像、Html等)注册为隐式值。由于额外的隐式定义,这会增加一些配置开销,但会产生更好的定制优势。这样我也摆脱了反射部分

implicit val image = Image.apply _



您可以使用类似于
CanBuildFrom
:使用隐式生成器创建合适的
请求的模式:

某些类型:

abstract class Content

class Bitmap extends Content

class Callbacks[T]

abstract class Request[C <: Content](val url: String, val event: Callbacks[C]) {
  def run: C
}

class ImageRequest(_url: String, _event: Callbacks[Bitmap]) 
  extends Request[Bitmap](_url, _event) {

  def run: Bitmap = {
    new Bitmap()
  }
}
要像这样使用:

GET[Image]( "http://...", null )
object GET {
  def apply[C <: Content](url: String, event: Callbacks[C])
                         (implicit rb: RequestBuilder[C]): C = {
    rb.create(url, event).run
  }
}

object HttpClient extends App {
  import ImplicitContainer._

  val bitmap = GET[Bitmap]("http://...", null)
  println(bitmap)
}
对象获取{
def应用[C]
abstract class Content

class Bitmap extends Content

class Callbacks[T]

abstract class Request[C <: Content](val url: String, val event: Callbacks[C]) {
  def run: C
}

class ImageRequest(_url: String, _event: Callbacks[Bitmap]) 
  extends Request[Bitmap](_url, _event) {

  def run: Bitmap = {
    new Bitmap()
  }
}
abstract class RequestBuilder[C <: Content] {
  def create(url: String, event: Callbacks[C]): Request[C]
}

class ImageRequestBuilder extends RequestBuilder[Bitmap]() {
  def create(url: String, event: Callbacks[Bitmap]): ImageRequest = {
    new ImageRequest(url, event)
  }
}

object ImplicitContainer {
  implicit val ImplicitImageRequestBuilder = new ImageRequestBuilder()
}
object GET {
  def apply[C <: Content](url: String, event: Callbacks[C])
                         (implicit rb: RequestBuilder[C]): C = {
    rb.create(url, event).run
  }
}

object HttpClient extends App {
  import ImplicitContainer._

  val bitmap = GET[Bitmap]("http://...", null)
  println(bitmap)
}