我希望将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
答案 0 :(得分:2)
实际上不建议使用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)]
的实例,则可以将上述函数-bug-编写为:
def seqOfAnyToSeqString(param : Seq[Any]) : Seq[(String, String)]
= param.collect {
case (x : String, y : String) => (x, y)
}
但是请注意,如果元素不符合(String, String)
,则会删除这些元素。
答案 1 :(得分:0)
如果要忽略所有非(String, String)
元素,请参见jrook's answer。另外,如果遇到非(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