Как определить метод scala с типом param, который не может быть Any
В приведенном ниже примере я хочу определить contains
метод, который не компилируется, если a
а также b
не одного базового типа.
- В
contains1
если, еслиa
являетсяSeq[Int]
и бString
,T
получаетсяAny
и он компилируется. Это не я хочу. - В
contains2
если, еслиa
являетсяSeq[Int]
и б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
привязка к контексту смущает меня, так как метод не имеет ничего общего с сортировкой / упорядочением.
1 ответ
Вы можете использовать оператор обобщенных ограничений типа =:=
,
Например:
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
Подробнее об ограничениях обобщенного типа здесь и здесь.
Как заметил LuisMiguelMejíaSuárez, вы также можете рассмотреть возможность использования B <:< A
вместо A =:= B
, Я не буду подробно останавливаться на различиях между этими двумя, потому что это описано в связанном ответе и статье, но вкратце, <:<
также позволит всем B
которые являются подтипом A
, пока =:=
нужны типы, чтобы точно соответствовать.