2013-03-12 179 views
4

我是Scala編程世界的新手但喜歡它。最近我已經開始將我的研究應用程序移植到Scala中,而我仍在掙扎的一件事是返回關鍵字。例如,在下面的代碼斯卡拉選項返回類型

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 
} 

而且如果加一個return關鍵字,然後編譯器抱怨

method `readDocument` has return statement; needs result tye 

很少有更多的額外信息,這是我延長

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

我敢肯定的返回類型爲'選項[ContainerMetaData]',你需要用'高清readDocument(...):選項[ContainerMetaData] = {爲...產生...}' – 2013-03-12 14:57:31

+1

開始Scala程序員的規則是「不要使用'return'!」 – 2013-03-12 15:20:56

+0

@RandallSchulz這個問題根本不是關於'return'的! – Impredicative 2013-03-12 15:26:08

回答

8

的問題是特質,那你缺少yield關鍵字爲for-comprehension。並且None最後也是不必要的,因爲理解將產生None,如果其中一個值丟失,並且在理解中不需要顯式創建Some,因爲它將創建Option無論如何。您的代碼HASE看起來像這樣(未測試)

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) 
    } 
} 
+0

你修好了它。在'for'作爲'Option'伴隨對象apply方法的參數之前,它將被雙重包裝。 – 2013-03-12 16:36:30

+0

是的,我剛剛從OP複製它,並沒有看到第一次。謝謝你的評論。 – drexin 2013-03-12 17:18:06

+0

刪除我原來的評論,以避免混淆。目前的計劃應該工作! – 2013-03-12 17:19:13