tipos incompatíveis: int não pode ser convertido em booleano
Estou interessado em saber por que C permite e java não. Portanto, estou interessado no sistema de tipos da linguagem, especificamente em sua força.
Há duas partes na sua pergunta:
Por que o Java não se converte int
emboolean
?
Isso se resume ao Java, que deve ser o mais explícito possível. É muito estático, muito "na sua cara" com seu sistema de tipos. Coisas que são convertidas automaticamente em outras linguagens não são assim, em Java. Você tem que escrever int a=(int)0.5
também. A conversão float
para int
perderia informações; o mesmo que converter int
paraboolean
e seria, portanto, propenso a erros. Além disso, eles teriam que especificar muitas combinações. Claro, essas coisas parecem óbvias, mas pretendiam errar com cautela.
Ah, e comparado a outras linguagens, o Java era imensamente exato em sua especificação, pois o bytecode não era apenas um detalhe interno da implementação. Eles teriam que especificar toda e qualquer interação, com precisão. Enorme empresa.
Por que if
não aceita outros tipos além de boolean
?
if
poderia perfeitamente ser definido de forma a permitir outros tipos que não boolean
. Poderia ter uma definição que diz o seguinte é equivalente:
true
int != 0
String
com .length>0
- Qualquer outra referência de objeto que não seja
null
(e não seja Boolean
com valor false
).
- Ou ainda: qualquer outra referência de objeto que não seja
null
e cujo método Object.check_if
(inventado por mim apenas para esta ocasião) retorne true
.
Eles não fizeram; não havia necessidade real e eles queriam que fosse o mais robusto, estático, transparente, fácil de ler etc. Sem recursos implícitos. Além disso, a implementação seria bem complexa, tenho certeza, tendo que testar cada valor para todos os casos possíveis, portanto o desempenho também pode ter desempenhado um pequeno fator (o Java costumava ser sloooow nos computadores daquele dia; lembre-se de que não havia compiladores JIT com os primeiros lançamentos, pelo menos não nos computadores que usei na época).
Razão mais profunda
Uma razão mais profunda pode muito bem ser o fato de o Java ter seus tipos primitivos, portanto, seu sistema de tipos é dividido entre objetos e primitivos. Talvez, se os tivessem evitado, as coisas tivessem acontecido de outra maneira. Com as regras fornecidas na seção anterior, eles teriam que definir a veracidade de cada primitivo explicitamente (uma vez que os primitivos não compartilham uma superclasse e não há um conjunto bem definido null
para os primitivos). Isso se tornaria um pesadelo, rapidamente.
Outlook
Bem, e no final, talvez seja apenas uma preferência dos designers de linguagem. Cada idioma parece girar seu próprio caminho até lá ...
Por exemplo, Ruby não tem tipos primitivos. Tudo, literalmente tudo, é um objeto. Eles têm um tempo muito fácil para garantir que cada objeto tenha um determinado método.
Ruby procura veracidade em todos os tipos de objetos que você pode jogar nele. Curiosamente, ele ainda não tem boolean
tipo (porque não tem primitivos) e também não tem Boolean
classe. Se você perguntar com que classe o valor true
tem (disponível com facilidade true.class
), você recebe TrueClass
. Essa classe realmente tem métodos, os 4 operadores para booleanos ( | & ^ ==
). Aqui, if
considera seu valor falsey se e somente se é um false
ou nil
(o null
de Ruby). Tudo o resto é verdade. Então, 0
ou ""
são verdadeiras.
Teria sido trivial para eles criar um método Object#truthy?
que pudesse ser implementado para qualquer classe e retornar uma veracidade individual. Por exemplo, String#truthy?
poderia ter sido implementado para ser verdadeiro para cadeias não vazias, ou outros enfeites. Eles não o fizeram, embora Ruby seja a antítese do Java na maioria dos departamentos (digitação dinâmica com mixin, reabertura de classes e tudo mais).
O que pode ser surpreendente para um programador Perl que está acostumado a $value <> 0 || length($value)>0 || defined($value)
ser verdadeiro. E assim por diante.
Digite SQL com a convenção de que null
dentro de qualquer expressão a torna automaticamente falsa, não importa o quê. Então (null==null) = false
. Em Ruby (nil==nil) = true
,. Tempos felizes.