Как кастовать типы коллекций Scala?Например, от Seq [Any] до Seq [(String, String)] без предупреждения - PullRequest
0 голосов
/ 17 октября 2018

Я хотел бы привести типы коллекций scala, например, Seq[Any] к Seq[(String, String)], без предупреждения.

Пример кода:

val seqs: Seq[Any] = Seq("1" -> "a", "2" -> "b")

def func(seqs: Seq[(String, String)]): String = {
}

func(seqs.asInstanceOf[Seq[(String, String)]]) // this will be warning

РЕДАКТИРОВАТЬна 2018-10-18:

Для лучшего понимания моего вопроса, вот мой реальный случай: у меня есть функция для обработки чего-либо с параметром Seq[Any], на самом деле, я желаю, чтобы этот параметр типаSeq[Int] или Seq[(String, String)]:

def getColumns(specifiedSegs: Seq[Any] = Seq.empty): Set[(String, String)] = {
  if (specifiedSegs.isEmpty) {
    // load all kvs from api
    loadAllFromMetaApi() // this will return a Set[(String, String)]
  } else {
    specifiedSegs.head match {
      case _: Int => ... // let's omission this
      case _: (String, String) => specifiedSegs.asInstanceOf[Seq[(String, String)]].toSet // warning!
    }
  }
}

, и когда я собираю проект, он выводит предупреждение на specifiedSegs.asInstanceOf[Seq[(String, String)]].toSet: warning: non-variable type argument String in type pattern (String, String) is unchecked since it is eliminated by erasure

Ответы [ 2 ]

0 голосов
/ 17 октября 2018

Если вы хотите игнорировать все элементы, не являющиеся (String, String), см. ответ jrook .В качестве альтернативы, вот способ сделать это, если вы хотите выдать конкретную ошибку при обнаружении элемента, не являющегося (String, String):

def convertSeq(seq: Seq[Any]): Seq[(String, String)] = seq map {
  case (x: String, y: String) => (x, y)
  case x => throw new IllegalArgumentException(s"$x is not type (String, String)")
}

например:

scala> def convertSeq(seq: Seq[Any]): Seq[(String, String)] = seq map {
     |   case (x: String, y: String) => (x, y)
     |   case x => throw new IllegalArgumentException(s"$x is not type (String, String)")
     | }
convertSeq: (seq: Seq[Any])Seq[(String, String)]

scala> convertSeq(Seq(("abc", "def"), ("ghi", "jkl")))
res0: Seq[(String, String)] = List((abc,def), (ghi,jkl))

scala> convertSeq(Seq(1, 2, 3))
java.lang.IllegalArgumentException: 1 is not type (String, String)
  at $anonfun$convertSeq$1.apply(<console>:13)
  at $anonfun$convertSeq$1.apply(<console>:11)
  at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:245)
  at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:245)
  at scala.collection.immutable.List.foreach(List.scala:381)
  at scala.collection.TraversableLike$class.map(TraversableLike.scala:245)
  at scala.collection.immutable.List.map(List.scala:285)
  at .convertSeq(<console>:11)
  ... 33 elided
0 голосов
/ 17 октября 2018

Использование asInstanceOf на самом деле не рекомендуется.Вы можете использовать функцию для достижения более плавного преобразования типов:

def seqOfAnyToSeqString(param : Seq[Any]) : Seq[(String, String)]
 = param.collect {
  case (x, y) => (x.toString, y.toString)
}

Для проверки этой функции:

val a  = Seq(1,2,3, 4 -> "b")
seqOfAnyToSeqString(a)

Выходы:

a: Seq[Any] = List(1, 2, 3, (4,b))
res0: Seq[(String, String)] = List((4,b))

Таким образом, она будет игнорироватьте элементы в последовательности, которые не определены как кортежи, но преобразуют все кортежи в кортежи строки.Я, конечно, предполагаю, что ввод достаточно прост и достаточно простого .toString.

РЕДАКТИРОВАТЬ:

В качестве альтернативы, как предлагается в комментариях, есливы абсолютно уверены, что последовательность является экземпляром Seq[(String, String)], вы можете написать приведенную выше функцию - , используя типовые описания - как:

def seqOfAnyToSeqString(param : Seq[Any]) : Seq[(String, String)]
     = param.collect {
      case (x : String, y : String) => (x, y)
    }

Но обратите внимание, что это приведет к удалению элементовесли они не соответствуют (String, String).

...