Jus12
Jus12

Reputation: 18024

Can we do conditional imports in Scala?

say I have the following code:

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

I import Foo as:

import my.{Foo => MyClass}

I want to be able to do something like:

If Chooser.isFoo, then:

import my.{Foo => MyClass}

else:

import my.{Bar => MyClass}

I have used Foo in my code as something like this:

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

Are there any hidden features of Scala that let me use Bar in place of Foo without modifying the code of MyObj at all. Also what would be the best way to design such code in future so that such extensions are easy?

Upvotes: 2

Views: 1522

Answers (2)

atline
atline

Reputation: 31584

Happen to see this old post & a little curious why it can't do conditional imports in Scala? Maybe old version limit, not sure? But see this, we can import in any place of scala code.

For your scenario, it could be:

try.scala:

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)
  }
}

run output:

C:\abc\abc>scalac try.scala

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

Upvotes: 2

johanandren
johanandren

Reputation: 11479

There isn't but I'm guessing you are more interested in different implementations at runtime than in conditional type import. Your Chooser.isFoo sounds like something that happens during runtime and not in the type system.

One example of how you could do it, since the common type for Foo and Bar is Foo:

val a: Foo = 
  if (Chooser.isFoo) new my.Foo
  else new my.Bar

Edit based on your edit: you could delay the choice by having an abstract type or a type parameter, like so:

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

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

Note the type bound that says that T must be a subclass of Foo, or else you wouldn't know anything about what you can do with a T.

Upvotes: 2

Related Questions