El Java es en realidad una solución para el problema de que no todas las expresiones devuelven valores, por lo que no se puede escribir esto en Java:
final String whatever = if (someCondition) {
"final value"
} else {
"other value"
}
Cada vez más, la tendencia en Java es utilizar el operador ternario en su lugar:
final String whatever = someCondition ? "final value" : "other value"
Lo que está bien para ese caso de uso limitado, pero totalmente insostenible una vez que empezar a tratar con los estados de conmutación y varios constructores.
El enfoque de Scala es diferente aquí. Toda construcción de objeto debe pasar finalmente a través de un único constructor "primario", todas las expresiones devuelven un valor (incluso si es Unit
, equivalente a Void
de Java), y la inyección del constructor es muy favorable. Esto da como resultado gráficos de objetos que se construyen de forma limpia como un Gráfico Acíclico Dirigido, y también funciona muy bien con objetos inmutables.
También debe tener en cuenta que declarar y definir variables en operaciones separadas es, en general, una mala práctica al tratar con múltiples hilos, y podría dejarlo vulnerable a exponer nulos y condiciones de carrera cuando menos lo espere (aunque esto no es realmente un problema durante la construcción del objeto). La creación atómica de valores inmutables es solo un aspecto de la forma en que los lenguajes funcionales ayudan a lidiar con la concurrencia.
También significa que el compilador de Scala puede evitar parte del análisis de flujo horriblemente complicado de la especificación de lenguaje de Java.
Como se ha indicado anteriormente, la Scala Way ™ es:
val whatever =
if (someCondition)
"final value"
else
"other value"
Un enfoque que también se amplía hasta otras estructuras de control:
val whatever = someCondition match {
case 1 => "one"
case 2 => "two"
case 3 => "three"
case _ => "other"
}
Con un poco de experiencia Scala descubrirá que este estilo ayuda al compilador a ayudarte, ¡y deberías escribir programas con menos errores!
¿Cómo se aseguraría el compilador de que se haya inicializado? Sí, es posible, pero difícil y no es necesario. – delnan
Porque hasta el momento de esa inicialización, el valor es * undefined * y simplemente tiene sentido en términos de un flujo de control siguiente. En la programación funcional, no hay valores indefinidos, y los valores, no los estados, son lo único que importa. – Dario
Bueno, básicamente no hay "sin inicializar". La JVM no es compatible con este concepto. En Java, estos campos "no inicializados" tienen el valor 'null'. Debido a la forma en que funciona la inicialización de clase, a veces es posible acceder a los campos y obtener nulos falsos. Esto lleva a un código que parece no sospechoso, pero arroja 'NPE's en tiempo de ejecución. La serialización/RMI agrega más problemas a ese enfoque. Si estás interesado, mira algunos ejemplos en "Puzzlers de Java". Básicamente: Scala evita que ocurran cosas extrañas y reduce la necesidad de valores no inicializados, porque todo es una expresión. – soc