为什么不是一个具有适用于迭代的不同类型元素的集合?

yu.*_*sun 1 scala

val signList1 = Set("(", "[", " VIA ")
val signList2 = Set('(', '[', " VIA ")
val returnStr2 = "xx VIA yy" 
var returnStr3 = returnStr2  
signList2.foreach(e => {
   val pos = returnStr2.indexOf(e)
   if (pos == 0) {
     returnStr3 = returnStr2.substring(pos + 1).trim
   }
   else if (pos > 0) {
     returnStr3 = returnStr2.substring(0, pos).trim
   }
}) 
println(returnStr3)
Run Code Online (Sandbox Code Playgroud)

returnStr3应该是xx,而它被赋予xx VIA yy如果我使用signList2同时给予xx当我使用signList1.这是为什么现象呢?欣赏它.

Lev*_*sey 5

你的问题是signList2是一个Set[Any].这反过来意味着在foreach,e是一个Any(相当于java.lang.Object),这使得普通java.lang.String.indexOf方法(需要一个char或一个String参数)不适用(即使所有的对象signList2都是char或String,它们的常见超类型是Any,这就是他们所知道的一切).

相反,Scala隐式转换returnStr2为一个实例scala.collection.immutable.StringOps,最终有一个indexOf方法需要一个Any.这导致尝试将String与失败的Char进行比较.

你可以通过e在indexOf调用中强制成为一个String 来获得你寻求的结果(例如通过调用e.toString).

一般来说,有一种类型的推断Any是一种糟糕的代码气味(可以说除了Akka,你需要咧嘴笑着承担它(或过渡到Akka Typed)).大多数(如果不是全部)Scala linters将标记其类型中包含的表达式Any.