Scala присваивает типу динамическое значение - PullRequest
0 голосов
/ 04 июля 2018

Я довольно новичок в Scala, и мне интересно, возможно ли каким-то образом динамически создать тип. На практике то, чего я хочу достичь, выглядит примерно так:

trait BaseAB
case class A(value: String) extends BaseAB
case class B(value: String) extends BaseAB

def build(name: String, m: String): BaseAB = {
  type t = name match {
    case "A" => A
    base "B" => B
  }
  new t(m)
}

Ответы [ 2 ]

0 голосов
/ 04 июля 2018

Ваш код работает почти как есть, но это не потому, что есть некие «типозначные переменные, определенные во время выполнения». Вместо этого это работает, потому что есть сопутствующие объекты, называемые A и B, которые имеют методы apply(s: String): A и apply(s: String): B, а также оба соответствуют типу String => BaseAB:

trait BaseAB
case class A(value: String) extends BaseAB
case class B(value: String) extends BaseAB

def build(name: String, m: String): BaseAB = {
  val t = name match {
    case "A" => A
    case "B" => B
  }
  t(m)
}

В этом фрагменте кода тип t выводится как String => BaseAB (возможно, с некоторыми дополнительными признаками маркера, такими как Serializable).

Если вы уверены, что есть только "A" и "B", вы также можете написать это как

  (if (name == "A") A else B)(m)

работает по той же причине.

0 голосов
/ 04 июля 2018

Вы можете просто создавать новые экземпляры в своих предложениях case, например

case "A" => A(m)
case "B" => B(m)

или вы можете создать частично примененную функцию, представляющую конструктор, и затем предоставить значение

def build(name: String, m: String): BaseAB = {
  val construct = name match {
    case "A" => A.apply _
    case "B" => B.apply _
  }
  construct(m)
} 

> build("A", "boo") 
res25: BaseAB = A("boo")
...