2016-11-30 10 views
1

私は別のライブラリに依存するライブラリを開発しています。依存関係は、自分のパッケージドメインにエイリアスして、基礎となるライブラリを私が開発しているユーザーから「隠す」ために、後でそのライブラリの再実装が可能であるように、package objectを持っています。私は、これはコンパイルが、import renamedfunctions._がスコープに何ももたらさない別名Scalaパッケージオブジェクト

object functions { 
    def identity(a: Any): Any = a 
    def toUpper(s: String): String = s.toUpperCase 
} 
object renamedfunctions { 
    import functions._ 
} 

含め、カップルの事を試してみました。私はまた、バッキングオブジェクトを拡張しようとしましたが、スカラオブジェクトは伸縮できません。誰も私が基礎となるライブラリを捏造することなくやろうとしていることを達成する方法を知っていますか?単に

答えて

4

一般的に、Scalaのパッケージでこれを行うことはできません。通常、あなたが希望だけローカルファイル内のパッケージ別名:

import scala.{ math => physics } 

scala> physics.min(1, 2) 
res6: Int = 1 

しかし、これはあなたが聞いて何をしません。パッケージ自体は値または型ではないため、パッケージ自体として割り当てることはできません。これらは失敗します:

type physics = scala.math 
val physics = scala.math 

パッケージオブジェクトを使用すると、その中のクラスではなく、具体的なメンバーを取得できます。たとえば、次のように

scala> val physics = scala.math.`package` 
physics: math.type = [email protected] 

scala> physics.min(1, 2) 
res0: Int = 1 

しかし、従来のパッケージに属するオブジェクトや種類は動作しません使用して:

scala> scala.math.BigDecimal(1) 
res1: scala.math.BigDecimal = 1 

scala> physics.BigDecimal(1) 
<console>:13: error: value BigDecimal is not a member of object scala.math.package 
     physics.BigDecimal(1) 
      ^

オクラホマので、あなたが何をすべき?

これを検討している理由は、使用しているライブラリの実装を隠しておき、後で簡単に置き換えることができるからです。その場合、別のインタフェースまたはオブジェクト(ファサード)内のライブラリを非表示にする必要があります。これは、ライブラリ内に含まれるすべてのメソッドと値を転送する必要があるわけではなく、実際に使用しているメソッドと値のみを転送する必要があるということではありません。このようにして、別のライブラリに移行する場合は、コードの残りの部分だけがファサードを参照するため、クラスを1つ変更する必要があります。例えば

、我々はscala.mathからminmaxを使用していたが、後に、より効率的なソリューションを提供して別のライブラリに置き換えることを望んでいた場合(そのようなものが存在する場合)、私たちはこのようなファサードを作成することができます。

scala.mathが交換されたとき、彼らは同じままことができるように
object Math { 
    def min(x: Int, y: Int): Int = scala.math.min(x, y) 
    def max(x: Int, y: Int): Int = scala.math.max(x, y) 
} 

他のすべてのクラスは、Math.minMath.maxを使用します。 Mathを特性(実装)から除外し、サブクラスまたはオブジェクト(たとえばScalaMath)に実装を提供して、クラスが異なる実装を注入できるようにすることもできます。あなたはパッケージオブジェクトで実装に移行したときにクライアントが壊れていないになるだろう

package object p { def f = 42 } 

package q { 
    object `package` { def f = p.f } 
} 
/* 
package object q { 
    val `package` = p.`package` 
} 
*/ 

package client { 
    import q.`package`._ 
    object Test extends App { 
    println(f) 
    } 
} 

+0

これは私の脳が合成できなかったパッケージオブジェクトのライブラリとエイリアシングをフォークする中間点です。少し退屈ですが、それは私により多くの制御を与える、ありがとう! –

1

val renamedfunctions = functions 

import renamedfunctions._ 

あなたはそれがScalaのライブラリ自体に行われている見ることができます:https://github.com/scala/scala/blob/2.12.x/src/library/scala/Predef.scala#L150

val Map = immutable.Map 
+0

これはクラス/オブジェクト/特性の文脈の中で、私が探していたものではなく、@ micheal-zajacが上記の理想的な答えを持っていたようです。ありがとう! –

2

残念ながら、コメントアウトされたコードは、コンパイラがクラッシュします。

関連する問題