【问题标题】:Scala Option return typeScala 选项返回类型
【发布时间】:2013-03-12 14:31:18
【问题描述】:

我是 Scala 编程世界的新手,但我很喜欢它。最近我开始将我的研究应用程序移植到 Scala 中,而我仍在苦苦挣扎的一件事是 return 关键字。例如在下面的代码中

def readDocument(dbobj:MongoDBObject) = Option[ContainerMetaData] 
{
  for(a <- dbobj.getAs[String]("classname");
      b <- dbobj.getAs[Long]("id"); 
      c <- dbobj.getAs[Long]("version");
      d <- dbobj.getAs[String]("description");
      e <- dbobj.getAs[String]("name");
      f <- dbobj.getAs[String]("tag");
      g <- dbobj.getAs[Int]("containertype");
      h <- dbobj.getAs[Date]("createddate")
  )
  {
      val ctype = ContainerType(g)
      val jodadt = new DateTime(h) 
      val data = new ContainerMetaData(a,b,c,d,e,f,ctype,jodadt)
      Some(data)
  }
  None
}

在上面的代码中,我收到错误消息:

type mismatch;  found   : None.type  required: om.domain.ContainerMetaData  

因此,如果我删除显式返回类型,则代码可以正常工作,但如果没有显式返回关键字,我将无法在 Some(data) 处终止我的代码。

def readDocument(dbobj:MongoDBObject)= 
{
  for(a <- dbobj.getAs[String]("classname");
      b <- dbobj.getAs[Long]("id"); 
      c <- dbobj.getAs[Long]("version");
      d <- dbobj.getAs[String]("description");
      e <- dbobj.getAs[String]("name");
      f <- dbobj.getAs[String]("tag");
      g <- dbobj.getAs[Int]("containertype");
      h <- dbobj.getAs[Date]("createddate")
  )
  {
      val ctype = ContainerType(g)
      val jodadt = new DateTime(h) 
      val data = new ContainerMetaData(a,b,c,d,e,f,ctype,jodadt)
      Some(data)
  }
  None
}

如果添加返回关键字,编译器会报错

method `readDocument` has return statement; needs result tye

更多信息,这是我正在扩展的特征

trait MongoDAOSerializer[T] {
    def createDocument(content:T) :  DBObject
    def readDocument(db:MongoDBObject) : Option[T]
}

【问题讨论】:

  • 我很确定返回类型是Option[ContainerMetaData],你需要def readDocument(...): Option[ContainerMetaData] = { for...yield... }
  • Scala 初学者的规则是“不要使用return!”
  • @RandallSchulz 这个问题根本不是关于return
  • OP 提到了几次使用它,即使没有代码示例显示它。

标签: scala


【解决方案1】:

问题是,您在 for-comprehension 中缺少 yield 关键字。最后的None也是不必要的,因为如果缺少其中一个值并且不需要在理解中显式创建Some,则for-comprehension将产生None,因为它将无论如何创建一个Option。您的代码看起来像这样(未经测试)

def readDocument(dbobj: MongoDBObject): Option[ContainerMetaData] = {
  for {
      a <- dbobj.getAs[String]("classname")
      b <- dbobj.getAs[Long]("id")
      c <- dbobj.getAs[Long]("version")
      d <- dbobj.getAs[String]("description")
      e <- dbobj.getAs[String]("name")
      f <- dbobj.getAs[String]("tag")
      g <- dbobj.getAs[Int]("containertype")
      h <- dbobj.getAs[Date]("createddate")
  } yield {
      val ctype = ContainerType(g)
      val jodadt = new DateTime(h) 
      new ContainerMetaData(a,b,c,d,e,f,ctype,jodadt)
  }
} 

【讨论】:

  • 你修好了它。在将 for 作为 Option 伴随对象应用方法的参数之前,它会被双重包装。
  • 是的,我只是从 OP 中复制的,一开始并没有看到。感谢您的评论。
  • 删除了我原来的评论以避免混淆。目前的方案应该可行!
猜你喜欢
  • 2017-02-08
  • 1970-01-01
  • 1970-01-01
  • 2021-02-11
  • 1970-01-01
  • 2012-11-28
  • 1970-01-01
  • 2020-07-19
  • 1970-01-01
相关资源
最近更新 更多