在下面的例子中,我想定义一个 contains
如果 a
则无法编译的方法和 b
不是相同的基本类型。
contains1
实现,如果 a
是 Seq[Int]
b 是 String
, T
导出为 Any
, 并编译。这不是我想要的。 contains2
实现,如果 a
是 Seq[Int]
b 是 String
,然后它不会编译。这种行为是我想要的。 def contains1[T](a: Seq[T], b: T): Boolean = a.contains(b)
println(contains1(Seq(1,2,3), "four")) // false
def contains2[T: Ordering](a: Seq[T], b: T): Boolean = a.contains(b)
println(contains2(Seq(1,2,3), "four")) // compilation error
// cmd7.sc:1: No implicit Ordering defined for Any.
// val res7 = isMatched(Seq(1,2,3), "s")
^
// Compilation Failed
但是,有没有更简单的方法来实现与
contains2
中相同的行为? ? Ordering
上下文绑定(bind)让我感到困惑,因为该方法与排序/排序完全无关。
最佳答案
您可以使用 广义类型约束 接线员 =:=
.
例如:
def contains[A,B](a: Seq[A], b: B)(implicit evidence: A =:= B): Boolean = a.contains(b)
进而:
println(contains1(Seq(1,2,3), "four")) //fails with Cannot prove that Int =:= String.
println(contains1(Seq("one"), "four")) //returns false
println(contains1(Seq("one", "four"), "four")) //true
更多关于广义类型约束 here和 here .
正如 LuisMiguelMejíaSuárez 所注意到的,您也可以考虑使用
B <:< A
而不是 A =:= B
.我不会详细说明这两者之间的区别,因为它在链接的答案和文章中有所描述,但简而言之,<:<
也将允许所有 B
是 A
的子类型, 而 =:=
需要类型完全匹配。
关于scala - 如何定义一个参数类型不能为 Any 的 scala 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56637005/