2016-04-17 5 views
2

Я только что нашел концепцию класса типа Scala и действительно так сильно. Проблема заключается в том, что все примеры, которые я нашел, помещают типы классов (объектов) под один объект (как здесь: http://danielwestheide.com/blog/2013/02/06/the-neophytes-guide-to-scala-part-12-type-classes.html)Автоматический импорт из нескольких неявных объектов

Возможно, это неправильно, но я являюсь другом одного файла в классе. Поэтому мне нравится делать классы типов в несколько файлов, что означает, что каждая реализация должна быть помещена в отдельный объект. Это теперь приводит к «проблеме», которую мне нужно импортировать каждую отдельную реализацию вручную. Для уточнения лучше здесь небольшой пример:

package sth 

import sth.like.Like 
import sth.like.StringLike._ 
import sth.like.IntLike._ 

object Application extends App { 
    def t[T](arg: T)(implicit l: Like[T]) = { 
     l.print(arg) 
    } 

    t(1) 
    t("Blub") 
} 

-

package sth.like 

trait Like[T] { 
    def print(arg: T) 
} 

-

package sth.like 

object IntLike { 
    implicit object LikeIntLike extends Like[Int] { 
     def print(arg: Int): Unit = println(s"INT $arg") 
    } 
} 

-

package sth.like 

object StringLike { 
    implicit object LikeStringLike extends Like[String] { 
     override def print(arg: String): Unit = println(s"STRING: $arg") 
    } 
} 

Это работает до сих пор. Я знаю, импорт подстановочных знаков в приложении не нужен, но это не главное. Как вы можете видеть, мне нужно импортировать как StringLike, так и IntLike в приложение, потому что иначе они недоступны для объекта Application.

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

ответ

3

Вы можете поместить ваши implicits внутри черты, а не объекты

trait IntLike { 
    implicit object LikeIntLike extends Like[Int] { 
    def print(arg: Int): Unit = println(s"INT $arg") 
    } 
} 

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

object IntLike extends IntLike 

Вы можете сделать то же самое для всех остальных экземпляров вашего класса типов:

trait StringLike { 
    implicit object LikeStringLike extends Like[String] { 
    override def print(arg: String): Unit = println(s"STRING: $arg") 
    } 
} 

object StringLike extends StringLike 

И в другом файле, вы можете объединить все черты вместе, как это:

object Implicits extends StringLike with IntLike 

и импорт просто объект Implicits, если вы хотите, чтобы все ваши импликации были в области видимости.

package sth 

import sth.like.Like 
import sth.like.Implicits._ 

object Application extends App { 
    def t[T](arg: T)(implicit l: Like[T]) = { 
    l.print(arg) 
    } 

    t(1) 
    t("Blub") 
} 

При желании можно подмешать черты вам нужно

object Application extends App with StringLike with IntLike { ... } 

или даже сделать

trait Implicits extends StringLike with IntLike 
object Implicits extends Implicits 

object Application extends App with Implicits { ... } 
0

Большое спасибо за ваш ответ. Но мне также нужно будет добавить новые классы типов вручную в Implicits, не так ли?

Не могу ли я использовать те объекты пакета по соображениям простоты, как здесь:

http://naildrivin5.com/scalatour/wiki_pages/PackageObjects/

?

Я имею в виду эту части:

package opower { 
    package object controller { 
     type Secured = org.springframework.security.access.annotation.Secured 
     type Controller = org.springframework.stereotype.Controller 
     ... 
    } 
} 

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

Или я не понимаю, что такое объект упаковки?

Смежные вопросы