Как определить метод 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, пока =:= нужны типы, чтобы точно соответствовать.

Другие вопросы по тегам