Scala: How to disable unverified warnings / is it correct to map card maps?

The test call uses a third-party function that returns Option[Any] . I know if this function returns a Map , it is a Map[String, Any] . In this case, I want to check the individual elements of the map.

 theFunction(...) match { case Some(m: Map[String, Any]) => m("some key") match { case some_condition => ... (my check) } case _ => fail("Invalid type") } 

But the compiler warns that case Some(m: Map[String, Any]) not installed. When I use Map[_,_] instead, the compiler is taken at the point where I check m("some key") .

How to suppress this warning or better: how to do it right? The only approach I can think of is something like

 theFunction(...) match { case Some(m: Map[_,_]) => val m1: Map[String, Any] = m.toSeq.map(t => t._1.asInstanceOf[String] -> t._2).toMap m1("some key") match { case some_condition => ... (my check) } } 

but in my eyes it looks ugly and introduces an unnecessary map conversion to Seq and vice versa.

+6
source share
3 answers

It is currently not possible to disable these warnings in Scala. There is an interesting discussion on the topic here . You can ignore the warning or use asInstanceOf :

 m.asInstanceOf[Map[String, Any]]("some key") match { ... } 

These types of runtime operations are error prone and usually indicate a bad type system. There are very few situations where a method should return Option[Any] . Almost any use of Any as the return type is the red flag in Scala.

+1
source

You can use unchecked annotation to suppress compiler warnings like these (for non-exhaustive matches and fruitless matches due to type erasure).

From the skaladok:

Annotations to indicate that an annotated object should not be considered for additional compiler checks. Specific applications include annotating the conformance expression object to suppress exhaustion warnings and annotating the type argument in the case of matching to suppress unverified warnings.

Such suppression should be used with caution, without which you can encounter scala.MatchError or java.lang.ClassCastException at run time. In most cases, you can and should turn to a warning rather than suppress it.

Example:

 val m: Any = Some(Map("a" -> 1, "b" -> "b")) m match { case Some(m: Map[String, Any]) => println("map") case None => println("None") } <console>:30: warning: non-variable type argument String in type pattern scala.collection.immutable.Map[String,Any] (the underlying of Map[String,Any]) is unchecked since it is eliminated by erasure case Some(m: Map[String, Any]) => println("map") 

We can add the @unchecked annotation to Map[String, Any] within the correspondence:

 m match { case Some(m: Map[String, Any] @unchecked) => println("I'm a map!") case None => println("None") } // Exiting paste mode, now interpreting. I'm a map! 

No more warnings. But this, obviously, is no safer than warning permission, and can lead to unexpected matching errors or ClassCastException s.

+21
source

Well, I'm not sure if this is related to the question, but you can wherever you want to add type annotations.

For example, I have

 type H = List[Int] def sum_dummy(h: H): Int = { if (isEmpty(h)) throw new NoSuchElementException() else (h:H @unchecked) match { case x::list => x + func(list) } } 

you can rewrite the example using case Nil for a full idiomatic scala, but I wrote it as an example of type annotation.

+1
source

Source: https://habr.com/ru/post/986300/


All Articles