2016-04-06 12 views
1

У меня есть простая функция Scala, которая генерирует Json-файл с Map[String, Any].Удаление предупреждения «исключено путем стирания» в Scala

def mapToString(map:Map[String, Any]) : String = { 
    def interpret(value:Any) = { 
     value match { 
     case value if (value.isInstanceOf[String]) => "\"" + value.asInstanceOf[String] + "\"" 
     case value if (value.isInstanceOf[Double]) => value.asInstanceOf[Double] 
     case value if (value.isInstanceOf[Int]) => value.asInstanceOf[Int] 
     case value if (value.isInstanceOf[Seq[Int]]) => value.asInstanceOf[Seq[Int]].toString.replace("List(", "[").replace(")","]") 
     case _ => throw new RuntimeException(s"Not supported type ${value}") 
     } 
    } 
    val string:StringBuilder = new StringBuilder("{\n") 
    map.toList.zipWithIndex foreach { 
     case ((key, value), index) => { 
     string.append(s""" "${key}": ${interpret(value)}""") 
     if (index != map.size - 1) string.append(",\n") else string.append("\n") 
     } 
    } 
    string.append("}\n") 
    string.toString 
    } 

Этот код работает нормально, но в компиляции он выдает предупреждающее сообщение.

Warning:(202, 53) non-variable type argument Int in type Seq[Int] (the underlying of Seq[Int]) 
is unchecked since it is eliminated by erasure 
     case value if (value.isInstanceOf[Seq[Int]]) => 
value.asInstanceOf[Seq[Int]].toString.replace("List(", "[").replace(")","]") 
               ^

Линия case value if (value.isInstanceOf[Seq[Int]]) вызывает предупреждение, и я попытался case value @unchecked if (value.isInstanceOf[Seq[Int]]) для удаленного предупреждения, но он не работает.

Как удалить предупреждение?

+1

Пожалуйста, взгляните на 'mkString', похоже, что ваша функция может быть упрощена. 'map.toList.map {case (k, v) => s" "" "$ k": $ {interp (v)} "" "} .mkString (" {\ n ",", \ n ", "\ n} \ n") ' –

+0

@ Łukasz: Это здорово. Благодаря! – prosseek

ответ

2

Если вы на самом деле не заботиться о типе компонента (и, кажется, вы делаете не так, как вы все это stringify его):

case value if (value.isInstanceOf[Seq[_]]) => 
    value.asInstanceOf[Seq[_]].toString.replace("List(", "[").replace(")","]") 

Давай думать об этом, вы должны быть в состоянии называют toString на что-нибудь так или иначе:

case value if (value.isInstanceOf[Seq[_]]) => 
    value.toString.replace("List(", "[").replace(")","]") 

но вместо toString следует баловаться с строкой рассмотрит Seq#mkString

value.mkString("[", ",", "]") 

Наконец, что картина isInstanceOf/asInstanceOf может быть заменен на матч (во всех случаях)

case value: Int => value // it's an Int already now, no cast needed 
case value: Seq[_] => value.mkString("[", ",", "]") 
1

Вы можете сделать следующее,

case value: String => ??? 
case value: Double => ??? 
case value: Int => ??? 
case value: Seq[Int] @unchecked => ??? 

или @Thilo упоминается

case value: Seq[_] => 
1

Это лучший код, который не генерирует предупреждающего сообщения (с подсказками от Thilo & Łukasz).

def mapToString(map:Map[String, Any]) : String = { 
    def interpret(value:Any) = { 
     value match { 
     case value:String => "\"" + value + "\"" 
     case value:Double => value 
     case value:Int => value 
     case value:Seq[_] => value.mkString("[",",","]") 
     case _ => throw new RuntimeException(s"Not supported type ${value}") 
     } 
    } 
    map.toList.map { case (k, v) => s""" "$k": ${interpret(v)}""" }.mkString("{\n", ",\n", "\n}\n") 
    }