2010-04-13 12 views
31

Sono nuovo di scala e sto riscontrando la necessità di convertire un valore booleano in un numero intero. So che posso usare qualcosa come if (x) 1 else 0 ma mi piacerebbe sapere se esiste un metodo preferito, o qualcosa di integrato nel framework (cioè toInt())C'è un modo semplice per convertire un booleano in un intero?

+3

Penso che se ci fosse un metodo nel quadro, sarebbe fare qualcosa di più simile a 'se (x) 1 altro 0', seguendo la tradizione C di 0 per falso e 1 per vero. –

+1

ho appena realizzato il mio errore e modificato il post. –

+0

Senza più contesto, direi che non è davvero una buona pratica. I booleani non sono interi, non convertirò implicitamente da uno all'altro ... Manterò la conversione esplicita, altrimenti potrebbe facilmente diventare davvero confuso. Il motto per le funzionalità avanzate di Scala è: "con un grande potere derivano grandi responsabilità" :) – GClaramunt

risposta

36

Se volete mescolare Boolean e Int funzionamento utilizza un implicit come sopra, ma senza creare una classe:

implicit def bool2int(b:Boolean) = if (b) 1 else 0 

scala> false:Int 
res4: Int = 0 

scala> true:Int 
res5: Int = 1 

scala> val b=true 
b: Boolean = true 


scala> 2*b+1 
res2: Int = 3 
+0

quali sono i vantaggi dell'utilizzo implicito senza una classe? –

+1

@Russ Bradberry, Se provi la risposta da @Jackson Davis devi chiamare esplicitamente la funzione asInt per fare la conversione così facendo ==> val a: Int = true non è possibile, e così facendo ==> (1- vero). La conversione non è trasparente. – Patrick

+0

quindi questo lo rende globale? o devo fare qualcosa di speciale per rendere questo globale? inoltre, funzionerà come se inserissi in mysql "" insert in blah (boolVal) values ​​("+ b +") "', assumerà automaticamente la sua versione int e non la versione bool? –

14

Lo si può fare facilmente con conversioni implicite:

class asInt(b: Boolean) { 
    def toInt = if(b) 1 else 0 
} 

implicit def convertBooleanToInt(b: Boolean) = new asInt(b) 

Poi, si otterrà qualcosa di simile

scala> false toInt 
res1: Int = 0 
+3

La convenzione di libreria è quella di usare 'toInt' - la stessa cosa sarebbe una buona idea qui. –

+0

abbastanza giusto, modificato per riflettere questo. –

+4

Questa grande tecnica si chiama "pimp my library". –

5

In realtà, mi aspetto che sia if (x) 1 else 0, non if (x) 0 else 1.

Ecco perché è necessario scrivere le proprie conversioni. L'intero non è un valore booleano, e se vuoi per qualche ragione archiviare i booleani come numeri interi, allora dovresti affinare i tuoi standard su come vengono rappresentate la verità e non la verità.

booleano "vero" non è un numero, è un esempio del tipo booleano. Come java.lang.Boolean.TRUE. Può essere memorizzato internamente come numero intero, ma questo è un dettaglio di implementazione che non dovrebbe essere trapelato nella lingua.

direi che if (x) 0 else 1 è il metodo preferito di conversione. È semplice e veloce

È possibile anche scrivere x match {case true => 0; case false => 1} se si desidera utilizzare un modello più generale di corrispondenza approccio.

+0

beh l'idea era di convertirla in lo standard c 0 = falso, 1 = vero. Ma perché dovrei usare la partita piuttosto che il ternario se altro? –

9

Quando si utilizza un implicit è probabilmente il modo migliore per andare, se si vuole una conversione rapida e-sporco da boolean a int è possibile utilizzare boolean.compare(false)

3

Dal Scala 2.10 la soluzione da Jackson Davis è più spesso scritto utilizzando an implicitvalue classe:

implicit class BoolToInt(val b:Boolean) extends AnyVal { 
    def toInt = if (b) 1 else 0 
    def * (x:Int) = if (b) x else 0 
} 

per una maggiore comodità ho anche aggiunto un operatore di moltiplicazione, in quanto questo è l'uso più comune di un valore booleano a Int conversione per me. Preferisco questo rendendo la conversione stessa implicita (soluzione fornita da Patrick), in quanto ciò perde più del controllo di tipo di quello che voglio.

3

Se non si vuole andare il modo implicito, questo può essere utile:

var myBool:Boolean = true 
myBool: Boolean = true 

myBool.compare(false) 
res3: Int = 1 

myBool = false 
myBool: Boolean = false 

myBool.compare(false) 
res3: Int = 0 
+0

Ho pensato la stessa cosa prima, ma il contratto di confronto promette solo un numero positivo per true.compare (false). Quindi potrebbe essere che un'implementazione JVM ritorni sth più grande di 1. –

Problemi correlati