2015-04-10 3 views
1

Это оригинальный метод, передавая в DatabaseType.Как совместить общий тип scala с признаком

trait DatabaseComponent 

class Database { 
    this: DatabaseComponent => 

} 

object Database { 
    def apply(dbType : DatabaseType): Unit ={ 
    val database = dbType match { 
     case DatabaseType.H2 => new Database with H2Component {} 
     case DatabaseType.MySQL => new Database with MySQLComponent {} 
     case DatabaseType.PostgresSQL => new Database with PostgresSQLComponent {} 
    } 
    } 
} 

Я хочу, однако, проходят в родовом типа и использование typeOf(T) как в C#

private void Apply<T>(){ 
    switch(typeOf(T)){ 
    Something 
    } 
} 

Я смотрю на этот пост How to match scala generic type?

Но я до сих пор не уверен, что это делается.

1) Что с неявным для этого val string = implicitly[ClassTag[String]]

2) Почему T должен быть подкласс ClassTag здесь implicitly[ClassTag[T]] match {

3) Должен ли я использовать ClassTag или TypeTag здесь?

ответ

1

1 и 2 вид имеют одинаковый ответ, вы можете прочитать о типах классов. Здесь класс type - ClassTag [T]. По сути, класс типа - это интерфейс, который может быть «присоединен» к любому типу через реализацию, называемую экземпляром класса type. В экземплярах Scala классы типов рассматриваются в неявной области, поэтому, хотя вы можете реализовать несколько разных экземпляров для типа, может быть не более одной реализации (или это неоднозначно). Если вы пишете что-то вроде

def method[T : TypeClass](p1, p2, ...) 

вы вынуждаете иметь экземпляр класса типов для типа T в области видимости при вызове метода. Обратите внимание, что это эквивалентно

def method[T](p1, p2, ...)(implicit val ev: TypeClass[T]) ... 

Итак, вы на самом деле скрытый параметр, который вы могли бы дать явно (!)

неявно [X] на самом деле метод, который получает любое неявное значение типа X, живущих в текущий объем. Вы можете на самом деле осуществить это самостоятельно:

def yourImplicitly[T](implicit val ev: T) : T = ev 

Есть тонны приложений для классов типа, как это своего рода плодотворной абстракции. Возможно, вы захотите ознакомиться с «проблемой расширения», поскольку типы классов являются решением проблемы расширения для языков FP.

На самом деле, может быть, вы можете сделать свой DatabaseComponent самим классом классов.

  1. Я не совсем уверен в ответе здесь, вы можете проверить http://docs.scala-lang.org/overviews/reflection/typetags-manifests.html. Если я правильно понимаю вашу проблему, то могут быть достаточно теги классов (и имхо проще использовать).
+0

Я не слышал, что описано, как проблема расширения - Вы имели в виду [проблема выражение] (https://en.wikipedia.org/wiki/Expression_problem)? – AlexFoxGill

+0

Да, вы правы. Однако это также связано с расширением (тщательно проверьте цитированные источники в связанной статье wiki). На самом деле проблема расширения может быть лучше. Поэтому я прав. – uberwach

0

Чтобы частично дополнить ответ на @uberwach

В отличие от C#, JVM имеет тип стирания, который стирает все даты типа во время выполнения. Таким образом, typeOf невозможно в Scala. Вы не можете создать новый экземпляр типа T во время выполнения.

Type erasure: Java vs C#