【问题标题】:How to handle different package names in different versions?如何处理不同版本的不同包名?
【发布时间】:2015-07-12 17:36:51
【问题描述】:

我有一个带有 foo.bar 包的 3rd 方库

我通常把它用作:

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
}

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

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

【问题讨论】:

    标签: scala scala-2.10


    【解决方案1】:

    另一个答案是在正确的轨道上,但并没有真正让你一路走到那里。在 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 处理。

    【讨论】:

      【解决方案2】:

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

      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 以切换到不同版本的库。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-09
        • 1970-01-01
        • 1970-01-01
        • 2014-08-16
        • 2019-09-21
        • 2020-05-19
        • 2012-04-09
        • 1970-01-01
        相关资源
        最近更新 更多