Как определить тип результата этого метода?

Как определить тип возвращаемого значения метода в следующем случае:

рабочий код

def deleteInstance(model: String, uid: Long) =  model match {
    case "menu" => Model.all(classOf[Menu]).filter("uid", uid).get().delete()
    case "articles" => Model.all(classOf[Articles]).filter("uid", uid).get().delete()
    case "news" => Model.all(classOf[News]).filter("uid", uid).get().delete()
    case "image" =>Model.all(classOf[Image]).filter("uid", uid).get().delete()
    case "files" =>Model.all(classOf[Files]).filter("uid", uid).get().delete()
    case _ => false
  }

нерабочий код:

class ModelManager{
  def getModel(model: String) = {
    model match{
      case "menu" => classOf[Menu]
      case "articles" => classOf[Articles]
      case _ => false
    }

  def deleteInstance(model:String, uid: Long) = {
    Model.all(getModel(model)).filter("uid", uid).get().delete()
  }    
 }
} 

Возникла ошибка:

рекурсивный метод getModel нуждается в типе результата

3 ответа

Решение

Похоже, вам нужна опция:

class ModelManager{
   def getModel(model: String) = model match {
      case "menu" => Some(classOf[Menu])
      case "articles" => Some(classOf[Articles])
      case _ => None
   }

   def deleteInstance(model:String, uid: Long) = 
      getModel(model) map { m => 
         Model.all(m).filter("uid", uid).get().delete()
      } getOrElse false
}

Вы можете думать о Option как о контейнере, который может содержать не более одного элемента. Опция, которая содержит элемент x является Some(x), Пустая опция None, Опция имеет несколько полезных методов, в том числе map а также getOrElse методы, используемые выше.

map Метод применяет функцию к каждому элементу "контейнера". Конечно, если контейнер None, он ничего не делает (кроме, возможно, для изменения статического типа опции). В вашем случае (при условии delete возвращает логическое значение), метод карты изменит Option[Class] на Option[Boolean].

getOrElse Метод возвращает элемент опции, если таковой имеется, и в противном случае возвращает значение по умолчанию (false в этом случае).

Обратите внимание, что вы также можете упростить вашу реализацию, используя condOpt метод, определенный в PartialFunction:

class ModelManager{
   def getModel(model: String) = condOpt(model) {
      case "menu" => classOf[Menu]
      case "articles" => classOf[Articles]
   }

   def deleteInstance(model:String, uid: Long) = 
      getModel(model) map { m => 
         Model.all(m).filter("uid", uid).get().delete()
      } getOrElse false
}

Похоже, что getModel иногда будет возвращать класс, а другие - логическое значение. В Scala это обычно моделируется с использованием класса Either:

def getModel(model: String) = {
    model match{
      case "menu" => Left(classOf[Menu])
      case "articles" => Left(classOf[Articles])
      case _ => Right(false)
    }

Левый и Правый представляют два возможных варианта выбора. Призыватели этого метода должны будут проверить возвращаемое значение (возможно, также используя сопоставление с образцом), чтобы решить, возвращал ли метод класс или логическое значение.

Кажется, вы не закрылись с паренсом в нужном месте. Вы имели в виду это?

class ModelManager{
  def getModel(model: String) = {
    model match{
      // snip
    }
  } // end method here

  def deleteInstance(model:String, uid: Long) = {
    Model.all(getModel(model)).filter("uid", uid).get().delete()
  }    
} 

Не похоже, что вы пытаетесь определить рекурсивный метод... Тогда у вас, вероятно, возникнут другие проблемы, требующие решения, так как вам нужен метод, который возвращает Class[_], а не комбинацию Boolean а также Class[_] (что будет Any). Так может быть, это будет работать лучше?

def getModel(model: String): Class[_] = {
  model match{
    case "menu" => classOf[Menu]
    case "articles" => classOf[Articles]
} // end method here
Другие вопросы по тегам