Respuestas:
Hay una publicación en el sitio web de Dart y lo explica bastante bien.
Final:
"final" significa asignación única: una variable o campo final debe tener un inicializador. Una vez asignado un valor, el valor de una variable final no se puede cambiar. final modifica las variables .
Const:
"const" tiene un significado que es un poco más complejo y sutil en Dart. const modifica los valores . Puede usarlo al crear colecciones, como const [1, 2, 3], y al construir objetos (en lugar de nuevos) como const Point (2, 3). Aquí, const significa que todo el estado profundo del objeto se puede determinar completamente en tiempo de compilación y que el objeto estará congelado y completamente inmutable.
Los objetos Const tienen un par de propiedades y restricciones interesantes:
Deben crearse a partir de datos que puedan calcularse en tiempo de compilación. Un objeto const no tiene acceso a nada que deba calcular en tiempo de ejecución. 1 + 2 es una expresión constante válida, pero la nueva DateTime.now () no lo es.
Son profunda, transitivamente inmutables. Si tiene un campo final que contiene una colección, esa colección aún puede ser mutable. Si tiene una colección constante, todo lo que contiene también debe ser constante, recursivamente.
Están canonicalizados . Esto es algo así como una cadena interna: para cualquier valor const dado, se creará un objeto const único y se reutilizará sin importar cuántas veces se evalúen las expresiones const.
Const:
Si el valor que tiene se calcula en tiempo de ejecución ( new DateTime.now()
por ejemplo), puede no utilizar una constante para él. Sin embargo, si el valor se conoce en el momento de la compilación ( const a = 1;
), debe usar const
más definal
. Hay otras 2 grandes diferencias entre const
y final
. En primer lugar, si está usando const
, debe declararlo en static const
lugar de solo const
. En segundo lugar, si tienes una const
colección, todo lo que está dentro está dentro const
. Si tiene una final
colección, todo lo que contiene no lo es final
.
Final:
final
debe usarse const
si no conoce el valor en tiempo de compilación, y se calculará / tomará en tiempo de ejecución. Si desea una respuesta HTTP que no se puede cambiar, si desea obtener algo de una base de datos o si desea leer desde un archivo local, use final
. Cualquier cosa que no se conozca en tiempo de compilación debería haber final
terminado const
.
Dicho todo esto, ambos const
y final
no se pueden reasignar, pero los campos en un final
objeto, siempre que no lo sean const
o final
se pueden reasignar (a diferencia const
).
const
y cuándo final
? ¿Conoces algún tipo de caso de uso para estos modificadores?
El valor debe conocerse en tiempo de compilación .
const birthday = "2008/12/26"
No se puede cambiar después de inicializado.
El valor debe conocerse en tiempo de ejecución .
final birthday = getBirthDateFromDB()
No se puede cambiar después de inicializado.
Consolidado @Meyi y @ faisal-naseer respuestas y comparación con poca programación.
La palabra clave const se usa para hacer que una variable almacene un valor constante de tiempo de compilación . El valor constante de tiempo de compilación es un valor que será constante durante la compilación :-)
Por ejemplo, 5
es una constante de tiempo de compilación. Mientras DateTime.now()
que no es tiempo de compilación constante. Porque este método devolverá el tiempo cuando la línea se ejecuta en tiempo de ejecución. Entonces no podemos asignar el DateTime.now()
a una const
variable.
const a = 5;
// Uncommenting below statement will cause compile time error.
// Because we can't able to assign a runtime value to a const variable
// const b = DateTime.now();
Debe inicializarse en la misma línea .
const a = 5;
// Uncommenting below 2 statement will cause compilation error.
// Because const variable must be initialized at the same line.
// const b;
// b = 6;
Todas las declaraciones mencionadas a continuación son aceptables.
// Without type or var
const a = 5;
// With a type
const int b = 5;
// With var
const var c = 6;
La variable const de nivel de clase debe inicializarse como a continuación.
Class A {
static const a = 5;
}
La variable const de nivel de instancia no es posible .
Class A {
// Uncommenting below statement will give compilation error.
// Because const is not possible to be used with instance level
// variable.
// const a = 5;
}
El otro uso importante de const
se usa para hacer que el objeto sea inmutable . Para hacer que un objeto de clase sea inmutable, necesitamos usar la palabra clave const con constructor y hacer que todos los campos sean finales como se menciona a continuación.
Class A {
final a, b;
const A(this.a, this.b);
}
void main () {
// There is no way to change a field of object once it's
// initialized.
const immutableObja = const A(5, 6);
// Uncommenting below statement will give compilation error.
// Because you are trying to reinitialize a const variable
// with other value
// immutableObja = const A(7, 9);
// But the below one is not the same. Because we are mentioning objA
// is a variable of a class A. Not const. So we can able to assign
// another object of class A to objA.
A objA = const A(8, 9);
// Below statement is acceptable.
objA = const A(10, 11);
}
podemos usar la palabra clave const para una lista .
const a = const [] - Una variable a
inicializada const
que contiene una lista de const
objetos (es decir, la lista debe contener solo objetos constantes de tiempo de compilación e inmutables). Entonces no podemos asignar a
con otra lista .
var a = const [] - Una variable a
inicializada como var
que contiene una lista de const
objetos . Entonces podemos asignar otra lista a la variablea
.
Class A {
final a, b;
const A(this.a, this.b);
}
class B {
B(){ // Doing something }
}
void main() {
const constantListOfInt = const [5, 6, 7,
// Uncommenting below statement give compilation error.
// Because we are trying to add a runtime value
// to a constant list
// DateTime.now().millisecondsSinceEpoch
];
const constantListOfConstantObjA = const [
A(5, 6),
A(55, 88),
A(100, 9),
];
// Uncommenting below 2 statements will give compilation error.
// Because we are trying to reinitialize with a new list.
// constantListOfInt = [8, 9, 10];
// constantListOfConstantObjA = const[A(55, 77)];
// But the following lines are little different. Because we are just
// trying to assign a list of constant values to a variable. Which
// is acceptable
var variableWithConstantList = const [5, 6, 7];
variableWithConstantList = const [10, 11, 15];
var variableOfConstantListOfObjA = const [A(5, 8), A(7, 9), A(10, 4)];
variableWithConstantList = const [A(9, 10)];
}
La palabra clave final también se usa para hacer que la variable mantenga un valor constante . Una vez inicializado, no podemos cambiar el valor.
final a = 5;
// Uncommenting below statement will give compilation error.
// Because a is declared as final.
// a = 6;
Todas las declaraciones mencionadas a continuación son aceptables.
// Without type or var
final a = 5;
// With a type
final int b = 5;
// With var
final var c = 6;
Puede asignar un valor de tiempo de ejecución .
// DateTime.now() will return the time when the line is getting
// executed. Which is a runtime value.
final a = DateTime.now();
var b = 5;
final c = b;
La variable final de nivel de clase debe inicializarse en la misma línea.
Class A {
static final a = 5;
static final b = DateTime.now();
}
La variable final de nivel de instancia debe inicializarse en la misma línea o en la inicialización del constructor. El valor se guardará en la memoria cuando se cree el objeto.
Class A {
final a = 5;
}
// Constructor with a parameter.
Class B {
final b;
B(this.b);
}
// Constructor with multiple parameter.
Class C {
final c;
C(this.c, int d) {
// Do something with d
}
}
void main() {
A objA = new A();
B objB = new B(5);
C objC = new C(5, 6);
}
Asignación de una lista .
final a = [5, 6, 7, 5.6, A()];
// Uncommenting Below statement will give compilation error.
// Because we are trying to reinitialize the object with another list.
// a = [9.9, 10, B()];
Extendiendo la respuesta por @Meyi
biggestNumberOndice
solo entonces el valor se inicializará y se asignará memoria).const es internamente de naturaleza final, pero la principal diferencia es que su constante de tiempo de compilación, que se inicializa durante la compilación, incluso si no usa su valor, se inicializará y ocupará espacio en la memoria.
La variable de las clases puede ser final pero no constante y si desea una constante a nivel de clase, haga que sea constante.
Código:
void main() {
// final demonstration
final biggestNumberOndice = '6';
// biggestNumberOndice = '8'; // Throws an error for reinitialization
// const
const smallestNumberOnDice = 1;
}
class TestClass {
final biggestNumberOndice = '6';
//const smallestNumberOnDice = 1; //Throws an error
//Error . only static fields can be declared as constants.
static const smallestNumberOnDice = 1;
}
Ambos final
y const
evitan que se reasigne una variable (similar a cómo final
funciona en Java o cómoconst
funciona en JavaScript).
La diferencia tiene que ver con cómo se asigna la memoria. La memoria se asigna para una final
variable en tiempo de ejecución y para una const
variable en tiempo de compilación. El final
modificador debería ser el más utilizado, porque muchas variables de programa no necesitarán memoria ya que la lógica del programa no requerirá que se inicialicen. Con unconst
variable, básicamente le está diciendo a la computadora: "Oye, necesito memoria para esta variable por adelantado porque sé que la voy a necesitar".
Pensar en ellos de esta manera hace que sea más fácil comprender las diferencias en su uso sintáctico. Principalmente que unfinal
variable puede ser una variable de instancia, pero a const
debe ser una static
variable en una clase. Esto se debe a que las variables de instancia se crean en tiempo de ejecución y las const
variables, por definición, no. Por lo tanto, las const
variables en una clase deben ser static
, lo que significa simplemente que existe una sola copia de esa variable en una clase, independientemente de si esa clase está instanciada.
Este video lo desglosa de manera bastante simple: https://www.youtube.com/watch?v=9ZZL3iyf4Vk
Este artículo profundiza y explica una diferencia semántica muy importante entre los dos, es decir, final
modifica las variables y const
modifica los valores, que esencialmente se reduce a solo poder inicializar const
valores que son derivables en tiempo de compilación.
https://news.dartlang.org/2012/06/const-static-final-oh-my.html
Si vienes desde C++
entonces const
adentro Dart
está constexpr
adentro C++
y final
adentro Dart
está const
adentro C++
.
Lo anterior se aplica solo a los tipos primitivos. Sin embargo, en los Dart
objetos marcados final
son mutables en términos de sus miembros.
const
en C ++ casi siempre se usa para especificar que un objeto no es mutable a través de una referencia o puntero específico. final
in Dart no evita que el objeto sea mutado a través de esa variable.
¿Cuándo usar qué palabra clave?
Un ejemplo simple para ambos: Use final: si no sabe cuál será su valor en tiempo de compilación. Por ejemplo, cuando puede necesitar obtener datos de una API, esto sucede cuando ejecuta su código.
Use const: si está seguro de que no se cambiará un valor al ejecutar su código. Por ejemplo, cuando declaras una oración que siempre permanece igual.
https://itnext.io/difference-between-const-and-final-in-dart-78c129d0c573
const
: stackoverflow.com/questions/51576209/… y la simple explotación afinal
es constante (no se puede reasignar o asignar una vez creada con la palabra clave final) y debe inicializarla una vez.