2013-04-24 2 views
0

Я новичок в генераторах scala, я прочитал несколько статей о представлениях, привязаны к границам/контексту. Когда я пытался реализовать свой класс, я был очень смущен.Scala Generics - T имеет ограничения метода

Мой вопрос, допустим, у меня есть класс шаблонов MyClass [T] {}. Я хочу, чтобы T должны иметь некоторые методы, например:

def func1(t:T):T 
def func2(t:T):Boolean 
def func3(t:T):Unit 

Примечание: классы, которые будут использовать MyClass не T поэтому я не могу использовать: < или:>

Я прочитал о Ordered and Ordering, которые имеют неявную функцию, но я до сих пор не могу понять, как ее реализовать.

Спасибо за хелперов

+1

Кстати, вам может быть интересно посмотреть на [структурные типы] (http://daily-scala.blogspot.ru/2010/02/introducing-structural-types.html). Не сказать, что это решит проблему выше, но может дать вам другой способ ее архивирования. –

+2

У Scala нет «классов шаблонов» в смысле C++. Он имеет общие классы в смысле Java/JVM. В частности (и игнорируя специализацию) он использует стирание типа для создания единого класса .class для универсального класса. Этот единственный класс JVM служит для _all_ экземпляров родового класса. –

+0

... и это [разница между * reified generics * (те, что указаны в .NET) и нереализованным (JVM)] (https://en.wikipedia.org/w/index.php?title=Comparison_of_C_Sharp_and_Java&oldid = 503563938 # Type_erasure_versus_reified_generics). –

ответ

1

Вы можете сделать это с помощью классов типов. Создание trait, который содержит методы, необходимые и для каждого типа, которые должны быть поддержаны создать неявный экземпляр:

trait MyTypeClass[T] { 
    def func1(t:T):T 
    def func2(t:T):Boolean 
    def func3(t:T):Unit 
} 

implicit object MyTypeClassInt extends MyTypeClass[Int] { 
    def func1(t:Int) = t + 2 
    def func2(t:Int) = t > 4 
    def func3(t:Int) = println(s"t is: $t") 
} 

Теперь, если вы добавите контекст, связанный с параметром типа в своем классе, он может быть реализован только , когда экземпляр для данного типа находится в области видимости.

class MyClass[A : MyTypeClass](a: A) 

scala> new MyClass(2) 
res0: MyClass[Int] = [email protected] 

scala> new MyClass("") 
<console>:11: error: could not find implicit value for evidence parameter of type MyTypeClass[String] 
       new MyClass("")** 

Вы можете получить доступ к экземпляру в классе по телефону implicitly[MyTypeClass[A]]. В качестве альтернативы вы можете сделать одно из следующих действий:

1.) Вместо того, чтобы использовать контекст, связанный добавить неявный параметр к классу:

class MyClass[A](a: A)(implicit ev: MyTypeClass[A]) 

2.) Добавить компаньон для класса типов, который имеет применить метод, который неявно получает экземпляр и возвращает его:

object MyTypeClass { 
    def apply[A](implicit ev: MyTypeClass[A]) = ev 
} 

и использовать его в своем классе, как это:

MyTypeClass[A].func1(a) 
Смежные вопросы