如何处理不同版本的不同包名?

时间:2015-07-12 17:36:51

标签: scala scala-2.10

我有一个包含foo.bar

的第三方库

我通常用它作为:

import foo.bar.{Baz => MyBaz}

object MyObject {
  val x = MyBaz.getX // some method defined in Baz
}

新版本的库已将包从foo.bar重命名为newfoo.newbar。我现在有另一个版本的代码,稍作修改如下:

import newfoo.newbar.{Baz => MyBaz}

object MyObject {
  val x = MyBaz.getX // some method defined in Baz
}

请注意,只有第一次导入是不同的。 有什么方法可以保留我的代码的相同版本,并在需要时仍在不同版本的第三方库之间切换?

我需要conditional imports之类的东西,或其他方式。

2 个答案:

答案 0 :(得分:2)

另一个答案是在正确的轨道上,但并没有真正让你一路走来。在Scala中执行此类操作的最常见方法是提供基本兼容性特征,每个版本具有不同的实现。例如,在我的小abstracted库中,我为Scala 2.10提供了以下MacrosCompat

package io.travisbrown.abstracted.internal

import scala.reflect.ClassTag

private[abstracted] trait MacrosCompat {
  type Context = scala.reflect.macros.Context

  def resultType(c: Context)(tpe: c.Type)(implicit
    tag: ClassTag[c.universe.MethodType]
  ): c.Type = {
    import c.universe.MethodType

    tpe match {
      case MethodType(_, res) => resultType(c)(res)
      case other => other
    }
  }
}

这是2.11:

package io.travisbrown.abstracted.internal

import scala.reflect.ClassTag

private[abstracted] trait MacrosCompat {
  type Context = scala.reflect.macros.whitebox.Context

  def resultType(c: Context)(tpe: c.Type): c.Type = tpe.finalResultType
}

然后我使用宏反射API的类,特征和对象可以只扩展MacrosCompat,他们将为版本获得适当的ContextresultType的实现我们目前正在构建(这是必要的,因为2.10和2.11之间的宏API发生了变化)。

(这不是我最初的想法或模式,但我不确定将其归于何处。可能是Eugene Burmako?)

如果您使用的是SBT,则会对特定版本的源树提供特殊支持 - 您的共享代码可以src/main/scala,例如版本特定代码的src/main/scala-2.10src/main/scala-2.11目录,SBT将负责其余的工作。

答案 1 :(得分:0)

您可以尝试使用类型别名:

package myfoo

object mybar {
  type MyBaz = newfoo.newbar.Baz
  // val MyBaz = newfoo.newbar.Baz // if Baz is a case class/object, then it needs to be aliased twice - as a type and as a value
}

然后您可以简单地import myfoo.mybar._并替换object mybar以切换到不同版本的库。