Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我们可以在Scala中进行条件导入吗?_Scala - Fatal编程技术网

我们可以在Scala中进行条件导入吗?

我们可以在Scala中进行条件导入吗?,scala,Scala,假设我有以下代码: package my class Foo class Bar extends Foo object Chooser { val isFoo = true } 我将Foo导入为: 我希望能够做到以下几点: 如果Chooser.isFoo,则: 其他: 我在代码中使用了Foo,如下所示: object MyObj { val a = new MyClass // ... } Scala是否有任何隐藏的特性可以让我在不修改MyObj代码的情况下使用Bar代

假设我有以下代码:

package my
class Foo 
class Bar extends Foo
object Chooser {
   val isFoo = true
} 
我将Foo导入为:

我希望能够做到以下几点:

如果Chooser.isFoo,则:

其他:

我在代码中使用了Foo,如下所示:

object MyObj {
   val a = new MyClass
   // ...
}

Scala是否有任何隐藏的特性可以让我在不修改MyObj代码的情况下使用Bar代替Foo。还有,将来设计这样的代码的最佳方法是什么,这样扩展就很容易了?

没有,但我猜您对运行时的不同实现比对条件类型导入更感兴趣。您的Chooser.isFoo听起来像是在运行时发生的,而不是在类型系统中发生的

由于Foo和Bar的常见类型是Foo,因此可以使用以下示例:

val a: Foo = 
  if (Chooser.isFoo) new my.Foo
  else new my.Bar
基于编辑进行编辑:您可以通过使用抽象类型或类型参数来延迟选择,如下所示:

class MyObj[T :> Foo] {
  val a: T
}

val anInstance = new MyObj[Foo]
val anotherInstance = new MyObj[Bar]

注意类型绑定,它说T必须是Foo的子类,否则你就不知道用T可以做什么。

碰巧看到这篇老文章&有点奇怪为什么它不能在Scala中进行条件导入?可能是旧版本的限制,不确定?但是请看,我们可以在任何地方导入scala代码

对于您的场景,可以是:

try.scala:

运行输出:


或者只是添加一个方法来选择def getObj=if isFoo new Foo else new Bar,然后让MyObj调用它。这将使MyObj类不再需要知道Foo的子类型。我需要条件导入,因为我使用的是Bar所需的某些库,这些库可以在一种情况下使用,但由于许可证的原因,无法在另一种情况下使用。如果我使用选择器,那么即使没有使用Bar,也需要提供这些库,如果我没有弄错的话。即使这是一个许可问题,您仍然只是在执行运行时功能检测。如果可以,可以分发Bar所需的库。在运行时,检测库是否存在。如果是,则返回一个Bar,否则返回一个Foo。Java应用程序通常使用服务提供者接口来实现这一点,Scala没有理由不能使用相同的JVM特性。基于Chooser.isFoo的选择发生在导入发生后的运行时。所以你所要求的是行不通的。如果您能提供一个facade来实现一个同时使用Foo和Bar库的API,那么将您的其余代码编写到该API中。然后提供两个实现facadeforbar,与Bar库绑定,facadeforfoo,与Foo库绑定?在后台,它需要两个库来编译。然而,我想要的是跳过编译时不需要的库。
object MyObj {
   val a = new MyClass
   // ...
}
val a: Foo = 
  if (Chooser.isFoo) new my.Foo
  else new my.Bar
class MyObj[T :> Foo] {
  val a: T
}

val anInstance = new MyObj[Foo]
val anotherInstance = new MyObj[Bar]
package my

class Foo {
}
class Bar extends Foo
object Chooser {
   val isFoo = true
}

object MyObj extends App {
  if (Chooser.isFoo) {
    import my.{Foo => MyClass}
    val a = new MyClass
    println(a)
  } else {
    import my.{Bar => MyClass}
    val a = new MyClass
    println(a)
  }
}
C:\abc\abc>scalac try.scala

C:\abc\abc>scala my.MyObj
my.Foo@6f4a47c7