2017-01-03 5 views
6

ich versuchte, eine Funktion zu schreiben, die nicht kompiliert werden, wenn null geben wird:Bedeutung von `A>: Null`?

$scala 
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_101). 
Type in expressions for evaluation. Or try :help. 

scala> :t null 
Null 

scala> def f[A >: Null](x: A):A = x 
f: [A >: Null](x: A)A 

Es ist jedoch nicht wie erwartet funktioniert:

scala> f(null) 
res1: Null = null 
+3

'Null' ist die untere Grenze, also ist es erlaubt, aber keine Subtypen von null sind erlaubt. – puhlen

+0

[Programmierung in Scala, 3. Ausgabe] (http: //www.artima.com/shop/programming_in_scala_3ed), Notizen: '" Supertype und Subtyp Beziehungen sind reflexiv, was bedeutet, ein Typ ist sowohl ein Super- Typ und ein Subtyp von sich selbst. "' –

+2

Das bedeutet, dass 'A' kann sowohl null sein alles größer als null. –

Antwort

6

Wie bereits erwähnt, A >: Null ermöglicht ANull selbst sein, aber das ist nicht einmal hier von Bedeutung. Selbst wenn A ein strenger Supertyp von Null sein müsste, wäre es immer noch möglich, null an f zu übergeben, da null ein gültiger Wert dieser Typen ist (was direkt aus der Tatsache folgt, dass Null ein Subtyp von ihnen ist).

Wenn Sie keine nullfähigen Typen akzeptieren möchten, muss A ein Subtyp von AnyVal sein. Beachten Sie, dass dadurch verhindert wird, dass Werte von Referenztypen übergeben werden - nicht nur null.

Es gibt keine Möglichkeit, Referenztypen zu akzeptieren, ohne auch null zu akzeptieren.

-1

A :> B bedeutet, dass A ein super- ist Art von B. A >: Null Diese Grenze bedeutet, dass A ein Super-Typ Null ist. Nullhas zwei Super-Typen Any und AnyRef.

In Scala können Sie Option als einen guten Mechanismus verwenden, um null Nutzung zu vermeiden.

Was denken Sie darüber?

1

Scala specification section 3.5.2 (conformance) Zustände (emphasis mir):

Die <: Beziehung bildet vorbestellbarer zwischen Typen, das heißt es ist transitive und reflexive. Die oberen und unteren unteren Grenzen einer Reihe von Typen sind relativ zu dieser Reihenfolge.

Also, wenn wir an der Typkonstruktor Erklärung von einem mathematischen Standpunkt aus betrachten, sehen wir die :< Beziehung wie:

Null <: T <: Any 

Da per Definition die Beziehung ist reflexiv, Null <: Null in der Beziehung ist, Dies macht null zu einem gültigen Wert, der an die Methode übergeben wird.

Wie @sepp2k zu Recht in den Kommentaren und in seiner Antwort gesagt hat, bedeutet die Tatsache, dass A nicht durch eine obere Grenze eingeschränkt ist, dass Any ein gültiger Kandidat ist, was bedeutet, dass ein Nullwert trotzdem übergeben werden könnte.

+0

Beachten Sie, dass dies eigentlich keine Rolle spielt. Wenn '<:' nicht reflexiv wäre und somit 'A' nur ein Supertyp wie' Any' sein könnte, wäre 'null' immer noch ein gültiges Argument wie jede Funktion, die' Any' akzeptiert (oder irgendetwas anderes, was nicht ist) 'AnyVal') akzeptiert' null' als sein Argument. – sepp2k

+0

@ sepp2k Ich stimme zu, aber ich wollte die Tatsache betonen, weil Kevin 'Null' als untere Grenze erklärte. Ein Kommentar hinzugefügt, um zu betonen. –