2013-03-12 5 views
4

Я новичок в мире программирования Scala, но люблю его. Недавно я начал переносить свое приложение для исследования в Scala, и одним из факторов, с которым я все еще сталкиваюсь, является ключевое слово return. Например, в поле ниже кодScala Option return type

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

Я уверен, что тип возвращаемого значения 'Опция [ContainerMetaData]' и вам необходимо определение функции readDocument (...): Опция [ContainerMetaData] = {для ... yield ...} ' –

+1

Правило для начинающих программистов Scala:« Не используйте 'return'!» –

+0

@RandallSchulz Этот вопрос не совсем о 'return' вообще! – Impredicative

ответ

8

Проблема в том, что вам не хватает ключевое слово yield для понимания. А также 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', поэтому он был бы дважды завернут. –

+0

Да, я просто скопировал его из ОП и не видел этого вначале. Спасибо за ваш комментарий. – drexin

+0

Удалил мой оригинальный комментарий, чтобы избежать путаницы. Текущая схема должна работать! –