2015-09-02 3 views
3

Я пишу функцию, чтобы получить запись от JSONObject. Так как это JSON, запись по имени ввода может быть или не существовать, и поэтому функция возвращает Option, которая будет None, когда Try терпит неудачу, или если значение равно NULL при успешном завершении. Функция не может скомпилировать и ошибки относительно неправильного типа возврата.Scala Тип опции не определяется как ожидалось

def tryGet[T](jsonObject: JSONObject, name: String): Option[T] = { 
    Try(jsonObject.get(name)) 
    .map(x => if(JSONObject.NULL.equals(x)) None else x.asInstanceOf[T]) 
    .toOption 
} 

Ошибка:

Expression of type Option[Any] doesn't conform to expected type Option[T]

Может кто-нибудь сказать мне, что я делаю неправильно здесь? Кроме того, это идиоматический подход к решению проблемы?

Update:

Изменение к ниже работ

def tryGet[T](jsonObject: JSONObject, name: String): Option[T] = { 
    Try(jsonObject.get(name)) 
     .filter(!JSONObject.NULL.equals(_)) 
     .map(_.asInstanceOf[T]) 
     .toOption 
} 

ответ

4

Проблема с этой линии:

.map(x => if(x.equals(null)) None else x.asInstanceOf[T]) 
This has type `Option[Nothing]`^  ^This has type `T` 

Вы одновременно Option[Nothing] и T в случае/else. Тип результата if/else - наименьшая верхняя граница (ближайший общий тип) результата результата if и тип результата else. В этом случае у них нет ничего общего, кроме Any. Таким образом, результат Try[Any], который преобразуется в Option[Any] по toOption.

Если вам действительно нужно проверить для null, используйте вместо этого filter.

def tryGet[T](jsonObject: JSONObject, name: String): Option[T] = 
    Try(jsonObject.get(name)) 
     .map(_.asInstanceOf[T]) 
     .filter(_ != null) 
     .toOption 
0

Я не думаю, что вам нужно проверить нулевой, и «None» и «Т» два возможных результата на карте, так тип будет отображаться в «Any» вместо «T» в вашем коде. Проверьте это:

Try(jsonObject.get(name)).map(_.asInstanceOf[T]).toOption 

Тогда вам может понадобиться что-то вроде этого:

val NullJson:Option[T] = None 
Try(jsonObject.get(name)).map(x=>if(x.equals(null)) NullJson else Option(x.asInstanceOf[T])).toOption.flatten 
+0

Да, я попробовал и он бросает «Exception в потоке„основной“java.lang.ClassCastException: org.json.JSONObject $ Null не может быть приведен к java.lang.String» во время выполнения, как он пытается отбросить значение null до строки. – broun

+1

@broun Вы должны написать, какую библиотеку json вы используете. Я думаю, что ваша библиотека json не возвращает 'null', вместо этого возвращает ненулевой объект' org.json.JSONObject $ Null' – ymonad

+0

Да, просто понял, что он возвращает пользовательский тип NULL. Я проверял java null вместо – broun

Смежные вопросы