2016-08-30 2 views
0

В Java можно применить только и ограничение типа связан, как это:Есть ли способ применить ИЛИ для привязки к Scala?

public class <T extends Serializable & SomeThingDoable> MyClass{ 
    //... 
} 

Но мы не могли сказать Java провести ИЛИ ограничения.

Можно ли в Scala, чтобы обеспечить ограничения, которые можно было бы добавить элемент в коллекцию тогда и только тогда это типа SomeType1ИЛИSomeType2

+0

Вы собираетесь проверить с помощью instanceof позже? – Ven

+0

@Ven образец соответствует – user3663882

+0

хорошо, поэтому экземпляр. Работы, так долго вы знаете тип erasure – Ven

ответ

1

Вы не можете сделать это с гарантией типа безопасности.

Я имею в виду, вы могли бы просто сделать instance и выбросить ошибку при создании экземпляра класса, но это довольно грязно.

Гораздо лучшим решением является использование (Типы данных Аннотация) ADT:

sealed trait NaturalNumber 
final case class Zero() extends NaturalNumber 
final case class Next(i: NaturalNumber) extends NaturalNumber 


object Main extends App { 
    val a: NaturalNumber = Next(Zero()) 
    a match { 
     case Zero() => "zero" 
    } 
} 

Что дает проверку exhaustivity:

<console>:16: warning: match may not be exhaustive. 
1

Я предложил бы использовать что-то вроде coproducts

Также обратите внимание, что Dotty будет иметь встроенные ограничения типа AND/OR.

0

не существует конструкции уровня языка, которая поддерживает это точно, но, как указывает @dveim, я считаю, что это скоро.

Если вы спрашиваете с конкретным практическим случаем использования, у вас есть несколько вариантов. вы можете использовать Either[SomeType1, SomeType2], в котором есть все конструкции, необходимые для представления этой идеи (но это не привязка к типу).

в качестве альтернативы, вы можете достичь этого эффекта, используя классы типов:

sealed trait Or[T] { 
    def someMethod(t: T): String 
} 

object Or { 
    implicit object OrInt extends Or[Int] { 
    def someMethod(t: Int): String = "int" 
    } 

    implicit object OrLong extends Or[Long] { 
    def someMethod(t: Long): String = "long" 
    } 
} 

object Test { 

    import Or._ 

    def test[T](value: T)(implicit or: Or[T]): String = 
    or.someMethod(value) 

} 

извини тривиальный пример, но то, что вы получаете здесь:

  • sealed trait, который означает, что вы можете ограничить другие от добавление большего количества экземпляров в семейство Or (если они не могут редактировать фактический файл, в котором он определен)
  • хорошо типизированный способ указать, какую функциональность вы хотите иметь ppen в двух разных случаях
Смежные вопросы