2013-10-29 17 views
5

Zastanawiam się, wywołując metodę, której argument może być lub nie być instancją value class. Ponieważ celem klas wartości jest uniknięcie boksowania wartości bazowej, jeśli typem parametru jest klasa wartości, wówczas dana metoda będzie w rzeczywistości wymagać wartości niezapakowanej. Aby obsłużyć tę sprawę, próbuję odwijać podstawową wartość z klasy wartości. I najpierw trzeba ustalić, czy argument jest z klasą wartości, a ja tu trafić na pierwszą przeszkodę:Scala: rozpoznawanie obiektów o klasach wartości

def isObjectOfValueClass(arg: Any) = 
    classOf[AnyVal].isAssignableFrom(arg.getClass) 

to nie działa zgodnie z oczekiwaniami, jako metoda zwraca true dla:

case class NonValueClass(underlying: Int) 

W jaki sposób można wdrożyć isObjectOfValueClass? Czy istnieje prostszy sposób refleksyjnego wywoływania metody, która może zająć obiekt klasy wartości jako argument?

+1

Nawiasem mówiąc, klasa wartości może owijać nie tylko prymitywy, ale również obiekty. –

Odpowiedz

3

Najpierw zwróć uwagę, że Twoja isObjectOfValueClass otrzyma pudełkową wersję instancji klasy wartości.

Po drugie, nie może działać tak, jak chcesz. To dlatego, że classOf[AnyVal] == classOf[AnyRef] == <java.lang.Object>.

Nie ma mowy Runtime odróżnić klasy wartości pudełkowej i klasy referencyjnej (Any nie ma .instanceOf[T], AnyVal nie może być stosowany w dopasowaniu wzoru lub jako parametr .instanceOf[T], a co najważniejsze, zajęcia Wartość skompilowane nie przedłużać lub wdrażać AnyVal).

Jeśli chcesz to zdecydowaliśmy się na czasie kompilacji, a następnie spróbuj:

case class IsAnyVal[-T](val value: Boolean) extends AnyVal 
implicit def _noClueHowToNameThisImplicit_1 = IsAnyVal[AnyVal](true) 
implicit def _noClueHowToNameThisImplicit_2 = IsAnyVal[AnyRef](false) 
def isAnyVal[T](arg: T)(implicit ev: IsAnyVal[T]) = ev.value 

scala> isAnyVal(1) 
res4: Boolean = true 

scala> isAnyVal("") 
res5: Boolean = false 

Nie jestem pewien, jak chcesz, aby wyodrębnić wyłączną pole wykrytych pudełkowych instancji klasy wartość bez bardziej przypadkowym boksu. Poza tym Hotspot jest całkiem niezły w optymalizacji małych krótkotrwałych obiektów.