2016-12-16 6 views
2

Scala Version 2.12.1-20161205-201300-2787b47Anruf `ConcurrentLinkedQueue.poll` auf leere Warteschlange scheint 0 zurück statt null

val max = 20 
val queue = new java.util.concurrent.ConcurrentLinkedQueue[Int]() 
(1 to 10).foreach(queue.offer) 
def show(c: Int): Unit = { 
    val e = queue.poll() 
    if(c < max && e != null) { 
     println(e) 
     show(c + 1) 
    } 
    } 
show(0) 

Repl Ausgang

1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
0 
0 
0 
0 
0 
0 
0 
0 
0 
0 

Was ist passiert?

+0

Sie können "null" keinem "Int" zuweisen (es ist kein Referenztyp). Also wird es in 0 umgewandelt. Die Verwendung von null wird in scala im Allgemeinen abgeraten. Dies ist einer der Gründe dafür. Sie schreiben Java-Code in Scala-Syntax, es ist nicht sehr nützlich. In die Scala-Denkweise einsteigen. – Dima

+0

@Dima Gibt es eine skalare Alternative zu 'ConcurrentLinkedQueue'? – jilen

Antwort

1

In Scala, Int erstreckt sich AnyVal. Typen, die erweitern, können nicht an einen null-Wert gebunden werden.

Dieser Code entspricht, da hinter den Abdeckungen zwischen Int und dem Integer Referenztyp Boxen und Unboxing stattfinden. Um zum Beispiel die ConcurrentLinkedQueue mit einem Integer zu setzen anstelle eines Int:

def apply$mcZI$sp(x$1: Int): Boolean = queue.offer(scala.Int.box(x$1)); 

Und Gleiches gilt, wenn Sie einen Wert über offer herausziehen, der Compiler tut:

val e: Int = unbox(queue.poll()); 

Wo unbox zu BoxesRunTime.unboxtoInt geht :

public static int unboxToInt(Object i) { 
    return i == null ? 0 : ((java.lang.Integer)i).intValue(); 
} 

Und deshalb sehen Sie 0 anstelle von null. Seien Sie vorsichtig, wenn Sie solche Interop zwischen Java-Klassen in Scala machen.

Verwandte Themen