2015-07-12 111 views
2

我有包第三方庫foo.bar如何處理不同版本的不同軟件包名稱?

我通常用它作爲:

import foo.bar.{Baz => MyBaz} 

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

庫的新版本改名爲包從foo.barnewfoo.newbar。我現在有一個我的代碼的另一個版本,如下所示:

import newfoo.newbar.{Baz => MyBaz} 

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

請注意,只有第一個導入是不同的。 有沒有什麼辦法可以保持我的代碼版本相同,並且在需要時仍然可以在不同版本的第三方庫之間切換?

我需要類似conditional imports或其他方法。

回答

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切換到不同版本的庫。

2

另一個答案是在正確的軌道上,但並不真正讓你在那裏。在Scala中做這種事最常見的方式是提供一個基本兼容性特徵,每個版本都有不同的實現。在我的小abstracted庫,例如,我有以下MacrosCompat斯卡拉2.10:

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,他們將得到適當的Context和我們當前正在構建的版本的resultType的實現(由於宏API在2.10和2.11之間發生更改,這是必要的)。

(這本來不是我的想法或模式,但我不知道是誰把它歸功於。大概尤金Burmako?)

如果您正在使用SBT,有一個爲特定版本的特殊支持源樹 - 你可以有一個src/main/scala爲你的共享代碼和例如src/main/scala-2.10src/main/scala-2.11用於特定於版本的代碼的目錄,而SBT將負責其餘部分。

相關問題