我正在使用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")
^
类型别名是否不适用于案例类?
答案 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)
您是否希望Foo
和Bar
可以区分(如果它们是不同的案例类)?如果是,并且您只是想避免重复字段列表,则可以执行以下操作:
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