2010-04-13 18 views
31

Soy nuevo en scala y encuentro la necesidad de convertir un valor booleano en un entero. Sé que puedo usar algo como if (x) 1 else 0 pero me gustaría saber si hay un método preferido, o algo integrado en el marco (es decir toInt())¿Existe una manera fácil de convertir un valor booleano a un número entero?

+3

Creo que si no había un método en el marco, sería hacer algo más parecido a 'si (x) 1 else 0', siguiendo la tradición C de 0 para falso y 1 para verdadero. –

+1

me acabo de dar cuenta de mi error y edité la publicación. –

+0

Sin más contexto, diría que no es realmente una buena práctica. Los booleanos no son enteros, no convertiré implícitamente de uno a otro ... Mantendré la conversión explícita, de lo contrario, puede ser muy confuso. El lema de las características avanzadas de Scala es: "con gran poder viene una gran responsabilidad" :) – GClaramunt

Respuesta

36

Si usted quiere mezclar Boolean y Int operación utiliza un implicit que el anterior pero sin crear una clase:

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

¿Cuáles son las ventajas de usar implícito sin una clase? –

+1

@Russ Bradberry, si intenta la respuesta de @Jackson Davis, tiene que llamar explícitamente la función como No para hacer la conversión, por lo que hacer ==> val a: Int = verdadero no es posible, y así lo hace ==> (1- cierto). La conversión no es transparente. – Patrick

+0

, ¿esto lo hace global? ¿o necesito hacer algo especial para que esto sea global? también, ¿funcionará esto como algo así como si inserto en mysql '" insert into blah (boolVal) values ​​("+ b +") "', asumirá automáticamente su versión int y no la versión bool? –

14

Esto se puede hacer fácilmente con las conversiones implícitas:

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

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

a continuación, obtendrá algo así como

scala> false toInt 
res1: Int = 0 
+3

La convención de la biblioteca es usar 'toInt'; la misma sería una buena idea aquí. –

+0

lo suficientemente justo, editado para reflejar eso. –

+4

Esta gran técnica se llama "proxeneta mi biblioteca". –

5

En realidad, me esperaba que fuera if (x) 1 else 0, no if (x) 0 else 1.

Es por eso que debe escribir sus propias conversiones. Integer no es un booleano, y si desea por alguna razón almacenar booleanos como enteros, entonces debe perfeccionar sus propios estándares de cómo se representa la verdad y no la verdad.

Booleano "verdadero" no es un número, es una instancia del tipo booleano. Me gusta java.lang.Boolean.TRUE. Se puede almacenar internamente como un entero, pero es un detalle de implementación que no debe filtrarse en el lenguaje.

Yo diría que if (x) 0 else 1 es el método preferido de conversión. Es simple y rápido.

También puede escribir x match {case true => 0; case false => 1} si desea utilizar un enfoque de coincidencia de patrones más general.

+0

y la idea era convertirlo a el estándar c 0 = falso, 1 = verdadero. ¿Pero por qué usaría el fósforo en vez del ternario si no es así? –

9

Mientras que el uso de un implicit es probablemente el mejor camino a seguir, si desea una conversión rápida y sucio de boolean a int puede utilizar boolean.compare(false)

3

Desde Scala 2.10 la solución por Jackson Davis es más a menudo escrito utilizando an implicitvalue clase:

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

para mayor comodidad también he añadido un operador de multiplicación, ya que esto es el uso más común de una conversión de Boole a Int para mí. Prefiero esto más que hacer que la conversión sea implícita (solución provista por Patrick), ya que eso pierde más control de tipo de lo que yo quiero.

3

Si no desea seguir el camino implícita, esto puede ser útil:

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

Pensé lo mismo primero, pero el contrato de comparación solo promete un número positivo para true.compare (falso). Entonces, puede ser que una implementación de JVM devuelva algo más grande que 1. –

Cuestiones relacionadas