具有任意类型属性的Scala类

时间:2012-12-18 00:48:37

标签: class scala types

我有一个代表我们系统中帖子的课程。帖子可能代表问题,文档,图像等.Post类可以表示大约7种不同类型的对象。我们拥有的7种不同类型的对象中的每一种都有自己的元数据类来存储其他对象特定信息。

目前我的Post类有7个可选属性,其中一个属性根据对象的类型而被填充。但是由于Post类只会填充这7个属性中的一个,有没有办法将这些属性合并为一个具有任意类型的属性?然后我可以使用匹配大小写语句在运行时生成正确的元数据对象。或者Scala给出了这种语言的强烈类型,这是不可能的。

代码如下:

    case class Post (
      id       : Long,
      typ      : String,
      name     : String,
      fileInfo : Option[FileInfo],
      imageInfo : Option[FileImageInfo],
      videoInfo : Option[FileVideoInfo],
      audioInfo : Option[FileAudioInfo],
      eventInfo: Option[EventInfo],
      lectureInfo: Option[LectureInfo],
      drawingInfo: Option[DrawingInfo]
    )


    object Post {

      val simple = {
        get[Long]("object_view.id") ~
        get[String]("object_view.type") ~
        get[String]("object_view.name") map {
          case id~typ~name =>
            Post(
                 id, 
                 typ, 
                 name, 
                 FileInfo.getById(id),
                 FileImageInfo.getById(id),
                 FileVideoInfo.getById(id),
                 FileAudioInfo.getById(id),
                 EventInfo.getFirst(id),
                 LectureInfo.getById(id),
                 DrawingInfo.getById(id)
          )
       }
    }

2 个答案:

答案 0 :(得分:1)

为什么不制作Post摘要,然后为每种不同类型的帖子实现一个子类? 类似的东西:

  abstract class Post { val id:Long; val typ:String; val name:String; }
  case class FilePost(
      id       : Long,
      typ      : String,
      name     : String,
      fileInfo : Option[FileInfo
  );
  case class ImagePost(
      id       : Long,
      typ      : String,
      name     : String,
      imageInfo : FileImageInfo
  );
  ...

  def doSomething( post:Post ):Unit = post match {
      case fp:FilePost => ...
    }

卫生署! - 看起来像早先的回应说同样的事情......

答案 1 :(得分:0)

class FileInfo(val name: String)
abstract trait CanGet[T] { val value: Option[T]; def get = value.get }
case class PostFileInfo(val id: Long, val typ: String, val name: String) extends 
  { val value = Some(new FileInfo(name)) } with CanGet[FileInfo]

...

(1L, "FileInfo", "FileName") match { 
  case (id, typ @ "FileInfo", name) => new PostFileInfo(1, typ, name)
}