在Scala 2.10中键入别名类案例类

时间:2014-02-17 14:21:05

标签: scala

我正在使用Scala 2.10.2,并且有两个具有相同字段的案例类:

case class Foo(id: String, name: String)
case class Bar(id: String, name: String)

我想做这样的事情:

case class Thing(id: String, name: String)
type Foo = Thing
type Bar = Thing

这是编译,但当我尝试创建Foo时,我得到:

scala> Bar("a", "b")
<console>:8: error: not found: value Bar
              Bar("a", "b")
              ^

类型别名是否不适用于案例类?

4 个答案:

答案 0 :(得分:15)

创建案例类时,Scala会自动为其创建一个伴随对象。在您的代码中,您可以为类型Thing定义别名,即仅为类Thing定义。您的伴随对象Thing仍然只有1个名称,没有别名。

“修复”它的一种方法是创建对伴随对象(不是类型别名)的引用,如下所示:

scala> val Bar = Thing
Bar: Thing.type = Thing

scala> Bar("a", "b")
res1: Thing = Thing(a,b)

“修复”它的另一种方法是使用import package.{Thing => Bar}重命名导入的对象。

答案 1 :(得分:5)

类型别名只是别名类型,而不是可能提供工厂方法的任何伴随对象(无论您是自己编写该工厂方法还是从编译器“免费”获取一个)。

另一方面,导入对名称的行为,如果有多个实体与给定名称相关联,则导入该名称会引入导入名称的每个引用对象。此外,您可以在导入时重命名,并且可以多次重命名,因此......

scala> object Stuff { case class Thing(id: String, name: String) }
defined module Stuff


scala> import Stuff.Thing
import Stuff.Thing

scala> import Stuff.{Thing => Foo}
import Stuff.{Thing=>Foo}

scala> import Stuff.{Thing => Bar}
import Stuff.{Thing=>Bar}


scala> val thing1 = Thing("fing", "fang")
thing1: Stuff.Thing = Thing(fing,fang)

scala> val foo1 = Foo("yes", "no")
foo1: Stuff.Thing = Thing(yes,no)

scala> val bar1 = Bar("true", "false")
bar1: Stuff.Thing = Thing(true,false)

通过toString进行渲染并不好,正如您所看到的那样。

答案 2 :(得分:4)

case class Thing(id: String, name: String)
type Foo = Thing
type Bar = Thing

如果你说new Bar("a","b")它会起作用

答案 3 :(得分:0)

您是否希望FooBar可以区分(如果它们是不同的案例类)?如果是,并且您只是想避免重复字段列表,则可以执行以下操作:

case class Foo(thing: Thing)
case class Bar(thing: Thing)

但这显然会使它们在模式匹配或访问字段中使用起来不那么方便。现场访问可以改进一点:

trait ThingWrapper {
  def thing: Thing
  def id = thing.id
  def name = thing.name
}

case class Foo(thing: Thing) extends ThingWrapper
case class Bar(thing: Thing) extends ThingWrapper