tipos incompatibles: int no se puede convertir a booleano
Estoy interesado en por qué C lo permite y Java no. Por lo tanto, estoy interesado en el sistema de tipos de lenguaje, específicamente su fortaleza.
Hay dos partes en su pregunta:
¿Por qué Java no convertir int
a boolean
?
Esto se reduce a que Java pretende ser lo más explícito posible. Es muy estático, muy "en tu cara" con su sistema de tipos. Las cosas que se convierten automáticamente en otros idiomas no lo son, en Java. Tienes que escribir int a=(int)0.5
también. La conversión float
a int
perdería información; lo mismo que convertir int
aboolean
y por lo tanto sería propenso a errores. Además, habrían tenido que especificar muchas combinaciones. Claro, estas cosas parecen ser obvias, pero pretendían errar por precaución.
Ah, y en comparación con otros lenguajes, Java fue enormemente exacto en su especificación, ya que el código de bytes no era solo un detalle de implementación interna. Tendrían que especificar cualquiera y todas las interacciones, precisamente. Enorme empresa.
¿Por qué if
no acepta otros tipos queboolean
?
if
perfectamente podría definirse como para permitir otros tipos que boolean
. Podría tener una definición que diga que los siguientes son equivalentes:
true
int != 0
String
con .length>0
- Cualquier otra referencia de objeto que no sea
null
(y no un Boolean
valor false
).
- O incluso: cualquier otra referencia de objeto que no sea
null
y cuyo método Object.check_if
(inventado por mí solo para esta ocasión) regrese true
.
No lo hicieron; no era realmente necesario, y querían tenerlo lo más robusto, estático, transparente, fácil de leer, etc. posible. Sin características implícitas. Además, la implementación sería bastante compleja, estoy seguro, tener que probar cada valor para todos los casos posibles, por lo que el rendimiento también puede haber jugado un pequeño factor también (Java solía ser lento en las computadoras de ese día; recuerde allí no había compiladores JIT con los primeros lanzamientos, al menos no en las computadoras que usé entonces).
Razón más profunda
Una razón más profunda podría ser el hecho de que Java tiene sus tipos primitivos, por lo tanto, su sistema de tipos está dividido entre objetos y primitivos. Tal vez, si hubieran evitado eso, las cosas habrían resultado de otra manera. Con las reglas dadas en la sección anterior, tendrían que definir la veracidad de cada primitiva explícitamente (ya que las primitivas no comparten una superclase, y no hay una bien definida null
para las primitivas). Esto se convertiría en una pesadilla, rápidamente.
panorama
Bueno, y al final, tal vez sea solo una preferencia de los diseñadores de idiomas. Cada idioma parece girar a su manera allí ...
Por ejemplo, Ruby no tiene tipos primitivos. Todo, literalmente todo, es un objeto. Les resulta muy fácil asegurarse de que cada objeto tenga un método determinado.
Ruby busca la veracidad en todos los tipos de objetos que puedes arrojarle. Curiosamente, todavía no tiene boolean
tipo (porque no tiene primitivas), y tampoco tiene Boolean
clase. Si pregunta qué clase tiene el valor true
(fácilmente disponible true.class
), obtiene TrueClass
. Esa clase realmente tiene métodos, a saber, los 4 operadores para booleans ( | & ^ ==
). Aquí, if
considera su valor falsey si y solo si es false
o nil
(el null
de Ruby). Todo lo demás es verdad. Entonces, 0
o ""
ambos son ciertos.
Hubiera sido trivial para ellos crear un método Object#truthy?
que podría implementarse para cualquier clase y devolver una verdad individual. Por ejemplo, String#truthy?
podría haberse implementado para ser verdadero para cadenas no vacías, o cualquier otra cosa. No lo hicieron, a pesar de que Ruby es la antítesis de Java en la mayoría de los departamentos (tipeo de pato dinámico con mixin, reapertura de clases y todo eso).
Lo que puede sorprender a un programador de Perl que está acostumbrado a $value <> 0 || length($value)>0 || defined($value)
ser veraz. Y así.
Ingrese SQL con su convención que null
dentro de cualquier expresión automáticamente lo hace falso, pase lo que pase. Por lo tanto (null==null) = false
. En Ruby, (nil==nil) = true
. Tiempos felices.