类似于此Scala: Why does Seq.contains take an Any argument, instead of an argument of the sequence type?
如果您这样做
Seq(1, 2, 3).contains("dasdas")
这将编译并始终返回false。是否有引发类型错误的替代方法?
这似乎是一个主要的wtf,其中contains
总是返回false
,并且在代码审查中非常容易错过。
答案 0 :(得分:6)
您可以启用-Xfatal-warnings
和-Ywarn-infer-any
使其在类型不匹配时失败。
这也适用于相等性检查==
。
以下是我在build.sbt
中使用的示例,以避免像您遇到的那样奇怪的Scala:
scalacOptions ++= Seq(
"-deprecation",
"-explaintypes",
"-feature",
"-language:higherKinds",
"-unchecked",
"-Xcheckinit",
"-Xfatal-warnings",
"-Xfuture",
"-Xlint",
"-Yno-adapted-args",
"-Ypartial-unification",
"-Ywarn-dead-code",
"-Ywarn-inaccessible",
"-Ywarn-infer-any",
"-Ywarn-nullary-override",
"-Ywarn-nullary-unit",
"-Ywarn-numeric-widen",
"-Ywarn-unused"
) ++ (
if (scalaVersion.value.startsWith("2.11")) Seq.empty
else Seq("-Ywarn-extra-implicit")
Rob Norris的精彩文章涉及以下内容:
https://tpolecat.github.io/2017/04/25/scalac-flags.html
仅供参考:Scala 3中的通用相等将被通用相等取代,以解决您的问题:
http://dotty.epfl.ch/docs/reference/contextual/multiversal-equality.html
答案 1 :(得分:4)
您可以编写扩展方法以仅接受定义的类型
implicit class ListOps[A](list: List[A]) {
def typeSafeContains(a: A) = list.contains(a)
}
List(1, 2, 3).typeSafeContains(1)
List(1, 2, 3).typeSafeContains("does not work") //type mismatch error;
题外话,但我选中了haskell has typesafe contains
Prelude> elem 1 [1,2,3]
True
Prelude> elem "should not work" [1,2,3]
<interactive>:6:25: error:
• No instance for (Num [Char]) arising from the literal ‘1’
• In the expression: 1
In the second argument of ‘elem’, namely ‘[1, 2, 3]’
In the expression: elem "should not work" [1, 2, 3]