2016-07-15 6 views
1

am Akka Suche docs für einen Schauspieler zu schaffen:Funktion, um irgendeinen Typ außer `AnyVal` zu akzeptieren?

The recommended approach to create the actor Props is not supported for cases when the actor constructor takes value classes as arguments.

Ist es möglich, eine Funktion zu definieren:

def anyTypeButValueClass[A : ...](x: A) = ???

wo A ist jede Art mit Ausnahme einer Wertklasse bei compile- Zeit?

Mein Verständnis ist, dass Wertklassen erweitern AnyVal (pro docs), aber es gibt auch:

The standard implementation includes nine AnyVal subtypes:

Double, Float, Long, Int, Char, Short, and Byte are the numeric value types.

Unit and Boolean are the non-numeric value types.

pro AnyVal.

Wie kann diese Funktion geschrieben werden?

+1

Für den 'AnyVal'-spezifischen Fall ist Lees Antwort genau richtig. Wenn Sie einen bestimmten Typ ausschließen möchten, überprüfen Sie http://stackoverflow.com/questions/7781782/type-parameter-does-not-extend-given-type –

Antwort

6

Die Scala type hierarchy zeigt, dass Any zwei direkte Subtypen hat, AnyRef und AnyVal für Referenz- bzw. Werttypen. Diese

bedeutet, dass Sie nur eine AnyRef Einschränkung hinzufügen:

def anyTypeButValueClass[A <: AnyRef](x: A) = ??? 
+0

Ist das nicht falsch, glaube ich, Gegenbeispiel ? 'Scala> anyTypeButValueClass (true) : 13: Fehler: gefolgert Typ Argumente [Boolean] nicht entsprechen Methode anyTypeButValueClass des Typs Parametergrenzen [A <: AnyRef]' –

+3

@KevinMeredith - Ist das nicht das Verhalten, das Sie wollen? 'Boolean' erweitert' AnyVal'. – Lee

+0

Mein Fehler - ich dachte, dass es eine Möglichkeit gibt, eine Werteklasse ("extend AnyVal") von einem Primitiv, z. 'true, Int, etc.' –

2

„jede Art akzeptieren, aber AnyVal“ an Enforce type difference beantwortet, aber es ist sehr verschieden von „jede Art übernehmen, die nicht AnyVal erstreckt“, Das unterscheidet sich wiederum von "Akzeptiere jeden Typ außer einer Wertklasse". Wertklassen erweitern AnyVal, aber auch die primitiven Typen.

Sie können es auf diese Weise tun:

// just a marker trait 
sealed trait NotAValueClass[A] 

object NotAValueClass { 
    implicit def AnyRefIsNotAValueClass[A <: AnyRef]: NotAValueClass[A] = new NotAValueClass[A] {} 
    implicit val IntIsNotAValueClass: NotAValueClass[Int] = new NotAValueClass[Int] {} 
    ... // same for other primitive types 
} 

def anyTypeButValueClass[A : NotAValueClass](x: A) = ... 
+0

Danke, Alexey. Bietet eine Bibliothek ('shapeless' usw.) bereits' NotAValueClass [A] 'out of the box? –

+0

Ich weiß es nicht, aber ich würde es nicht erwarten. –

+0

@KevinMeredith, nicht speziell für 'AnyVal', aber formlos bietet ein Dienstprogramm" nicht Subtyp von ". Siehe meine Antwort für Details. –

1

Wenn Sie bereit sind, eine Bibliothek wie shapeless zu verwenden, können Sie es auch kodieren wie

import shapeless._ 

def anyTypeButValueClass[A: |¬|[AnyVal]#λ](x: A) = x 

ref: https://github.com/milessabin/shapeless/blob/master/core/src/main/scala/shapeless/package.scala#L54

Beispiel:

@ def anyTypeButValueClass[A: |¬|[AnyVal]#λ](x: A) = x 
defined function anyTypeButValueClass 

@ anyTypeButValueClass(42) 
Compilation Failed 
Main.scala:296: ambiguous implicit values: 
both method nsubAmbig1 in package shapeless of type [A, B >: A]=> shapeless.<:!<[A,B] 
and method nsubAmbig2 in package shapeless of type [A, B >: A]=> shapeless.<:!<[A,B] 
match expected type shapeless.<:!<[Int,AnyVal] 
anyTypeButValueClass(42) 
       ^
@ anyTypeButValueClass("foo") 
res0: String = "foo" 
Verwandte Themen