2010-04-13 7 views
31

Je suis nouveau à scala et je trouve le besoin de convertir une valeur booléenne en nombre entier. Je sais que je peux utiliser quelque chose comme if (x) 1 else 0 mais je voudrais savoir s'il existe une méthode préférée, ou quelque chose de construit dans le cadre (c.-à-toInt())Existe-t-il un moyen facile de convertir un booléen en un entier?

+3

Je pense que s'il y avait une méthode dans le cadre, ce serait faire quelque chose plus proche de 'si (x) 1 sinon 0', suivant la tradition C de 0 pour faux et 1 pour vrai. –

+1

Je viens de réaliser mon erreur et édité le post. –

+0

Sans plus de contexte, je dirais que ce n'est pas vraiment une bonne pratique. Les booléens ne sont pas des entiers, je ne convertirai pas implicitement de l'un à l'autre ... Je garderai la conversion explicite, sinon ça pourrait facilement devenir vraiment confus. La devise pour les fonctionnalités avancées de Scala est: "avec une grande puissance vient une grande responsabilité" :) – GClaramunt

Répondre

36

Si vous voulez mélanger Boolean et Int opération utilisez un implicit comme ci-dessus, mais sans créer une 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

Quels sont les avantages de l'utilisation implicite sans classe? –

+1

@Russ Bradberry, Si vous essayez la réponse de @Jackson Davis vous devez appeler explicitement la fonction asInt pour faire la conversion en faisant ==> val a: Int = true n'est pas possible, et ce faisant ==> (1- vrai). La conversion n'est pas transparente. – Patrick

+0

alors est-ce que c'est global? ou dois-je faire quelque chose de spécial pour rendre cela global? aussi, cela fonctionnera-t-il comme quelque chose comme si j'insère dans mysql '" insert dans blah (boolVal) valeurs ("+ b +") "', assumera-t-il automatiquement la version int et non la version bool? –

14

Vous pouvez le faire facilement avec les conversions implicites:

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

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

Ensuite, vous obtiendrez quelque chose comme

scala> false toInt 
res1: Int = 0 
+3

La convention de la bibliothèque est d'utiliser 'toInt' - la même chose serait une bonne idée ici. –

+0

assez juste, édité pour refléter cela. –

+4

Cette grande technique est appelée "proxénète ma bibliothèque". –

5

En fait, je pense que ce soit if (x) 1 else 0, non if (x) 0 else 1. C'est pourquoi vous devriez écrire vos propres conversions. Entier n'est pas un booléen, et si vous voulez pour une raison quelconque stocker des booléens comme des entiers, alors vous devriez affiner vos propres normes de la façon dont la vérité et non la vérité sont représentées. Boolean "true" n'est pas un nombre, c'est une instance du type booléen.

Comme java.lang.Boolean.TRUE. Il peut être stocké en interne sous la forme d'un entier, mais il s'agit d'un détail d'implémentation qui ne doit pas être divulgué dans la langue.

Je dirais que if (x) 0 else 1 est la méthode de conversion préférée. C'est simple et rapide.

Vous pouvez également écrire x match {case true => 0; case false => 1} si vous souhaitez utiliser une approche de correspondance de modèle plus générale.

+0

bien l'idée était de le convertir en le standard c 0 = faux, 1 = vrai. Mais pourquoi devrais-je utiliser match plutôt que le ternaire sinon? –

9

Lors de l'utilisation d'un implicit est probablement la meilleure façon d'aller, si vous voulez une conversion rapide et sale de boolean à int vous pouvez utiliser boolean.compare(false)

3

Depuis Scala 2.10 la solution par Jackson Davis est le plus souvent écrit en utilisant 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 
} 

pour plus de confort, je l'ai également ajouté un opérateur de multiplication, comme cela est l'utilisation la plus courante d'une conversion booléenne Int pour moi. Je préfère cela à ce que la conversion elle-même soit implicite (solution fournie par Patrick), car elle perd plus de contrôle de type que je ne le souhaite.

3

Si vous ne voulez pas aller dans le sens implicite, cela peut être 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

Je pensais la même chose en premier, mais le contrat de comparaison ne promet qu'un nombre positif pour true.compare (false). Il se peut donc qu'une implémentation JVM renvoie sth plus grand que 1. –

Questions connexes