Was ist der Unterschied zwischen den Schlüsselwörtern "const" und "final" in Dart?

171

Was ist der Unterschied zwischen constund finalSchlüsselwort in Dart?

Ishmal Ijaz
quelle
1
Hier einige Details zu const: stackoverflow.com/questions/51576209/… und die einfache Explonation zu finalist konstant (kann nicht neu zugewiesen oder zugewiesen werden, sobald sie mit dem endgültigen Schlüsselwort erstellt wurde), und Sie müssen sie einmal initialisieren.
Blasanka

Antworten:

233

Es gibt einen Beitrag auf der Website von dart, der ihn ziemlich gut erklärt.

Finale:

"final" bedeutet Einzelzuweisung: Eine endgültige Variable oder ein endgültiges Feld muss einen Initialisierer haben. Sobald ein Wert zugewiesen wurde, kann der Wert einer endgültigen Variablen nicht mehr geändert werden. final ändert Variablen .


Const:

"const" hat eine Bedeutung, die in Dart etwas komplexer und subtiler ist. const ändert Werte . Sie können es verwenden, wenn Sie Sammlungen wie const [1, 2, 3] erstellen und wenn Sie Objekte (anstelle von neuen) wie const Point (2, 3) erstellen. Hier bedeutet const, dass der gesamte tiefe Zustand des Objekts vollständig zur Kompilierungszeit bestimmt werden kann und dass das Objekt eingefroren und vollständig unveränderlich ist.

Const-Objekte haben einige interessante Eigenschaften und Einschränkungen:

Sie müssen aus Daten erstellt werden, die zur Kompilierungszeit berechnet werden können. Ein const-Objekt hat keinen Zugriff auf alles, was Sie zur Laufzeit berechnen müssten. 1 + 2 ist ein gültiger const-Ausdruck, new DateTime.now () jedoch nicht.

Sie sind zutiefst transitiv unveränderlich. Wenn Sie ein letztes Feld haben, das eine Sammlung enthält, kann diese Sammlung weiterhin veränderbar sein. Wenn Sie eine const-Auflistung haben, muss alles darin auch rekursiv const sein.

Sie sind kanonisiert . Dies ähnelt einer internen Zeichenfolge: Für jeden gegebenen const-Wert wird ein einzelnes const-Objekt erstellt und wiederverwendet, unabhängig davon, wie oft die const-Ausdrücke ausgewertet werden.


Was bedeutet das?

Const:
Wenn der Wert, den Sie haben, zur Laufzeit berechnet wird ( new DateTime.now()zum Beispiel), können Sie keine const dafür verwenden. Wenn der Wert jedoch zur Kompilierungszeit bekannt ist ( const a = 1;), sollten Sie constover verwenden final. Es gibt zwei weitere große Unterschiede zwischen constund final. Erstens, wenn Sie verwenden const, müssen Sie es als static constund nicht nur deklarieren const. Zweitens, wenn Sie eine constSammlung haben, ist alles darin enthalten const. Wenn Sie eine finalSammlung haben, ist nicht alles darin final.

Final: Sollte
finalverwendet werden, constwenn Sie den Wert zur Kompilierungszeit nicht kennen, und er wird zur Laufzeit berechnet / abgerufen. Wenn Sie eine HTTP-Antwort wünschen, die nicht geändert werden kann, wenn Sie etwas aus einer Datenbank abrufen möchten oder wenn Sie aus einer lokalen Datei lesen möchten, verwenden Sie final. Alles , was nicht bekannt ist , wird bei der Kompilierung soll finalüber const.


Wenn all dies gesagt ist, können beide constund finalnicht neu zugewiesen werden, aber Felder in einem finalObjekt können (im Gegensatz zu ) neu zugewiesen werden , solange sie nicht constoder finalnicht zugewiesen werden const.

Meyi
quelle
3
Das Schlüsselwort const wird verwendet, um eine Konstante zur Kompilierungszeit darzustellen. Mit dem Schlüsselwort const deklarierte Variablen sind implizit endgültig.
Arun George
1
@Meyi, wann sollen wir verwenden constund wann final? Kennen Sie einen Anwendungsfall für diese Modifikatoren?
CopsOnRoad
4
@CopsOnRoad Sie könnten dieses Video aus Dart Const vs Final
Lemuel Ogbunude
2
Dieser letzte Satz fasst es wirklich so gut zusammen. Dank dafür.
Yster
Sollte es uns überhaupt etwas ausmachen, dass const eine Option ist? Ist der Leistungszuwachs wirklich spürbar?
CodeGrue
59

Const

Der Wert muss zur Kompilierungszeit bekannt sein . const birthday = "2008/12/26"
Kann nach der Initialisierung nicht geändert werden.


Finale

Der Wert muss zur Laufzeit bekannt sein . final birthday = getBirthDateFromDB()
Kann nach der Initialisierung nicht geändert werden.

Haroun Hajem
quelle
9
Die einfachste und beste Erklärung.
Ankur Lahiry
1
liebte dieses :)
Faisal Naseer
43

Konsolidierte Antworten von @Meyi und @ faisal-naseer und Vergleichen mit wenig Programmierung.

const:

Das Schlüsselwort const wird verwendet, um eine Variable zum Speichern eines Konstantenwerts für die Kompilierungszeit zu erstellen . Der Wert für die Kompilierungszeitkonstante ist ein Wert, der beim Kompilieren konstant bleibt :-)

Zum Beispiel 5ist eine Kompilierungszeitkonstante. Während DateTime.now()das nicht Kompilierzeitkonstante ist. Weil diese Methode die Zeit zurückgibt, zu der die Zeile zur Laufzeit ausgeführt wird. Wir können das also nicht DateTime.now()einer constVariablen zuordnen .

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();

Sollte in derselben Zeile initialisiert werden .

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;

Alle unten genannten Aussagen sind akzeptabel.

// Without type or var
const a = 5;
// With a type
const int b = 5;
// With var
const var c = 6;

Die Konstantenvariable auf Klassenebene sollte wie folgt initialisiert werden.

Class A {
    static const a = 5;
}

Konstante Variable auf Instanzebene ist nicht möglich .

Class A {
    // Uncommenting below statement will give compilation error.
    // Because const is not possible to be used with instance level 
    // variable.
    // const a = 5;
}

Die andere Hauptverwendung von constwird verwendet, um das Objekt unveränderlich zu machen . Um ein Klassenobjekt unveränderlich zu machen, müssen wir das Schlüsselwort const mit dem Konstruktor verwenden und alle Felder wie unten erwähnt als endgültig festlegen.

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);
}

Wir können das Schlüsselwort const für eine Liste verwenden .

const a = const [] - Eine a initialisierteconstconst Variable, die eine Liste von Objekten enthält (dh die Liste sollte nur Kompilierungszeitkonstanten und unveränderliche Objekte enthalten). So können wir zuordnen nicht in der Lage amit einer anderen Liste .

var a = const [] - Eine Variable a initialisiert , wie vardie eine Liste enthält constObjekte . So können wir der Variablen eine andere Liste zuweisena .

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)];
}

Finale:

Das Schlüsselwort final wird auch verwendet, um die Variable so zu gestalten , dass sie einen konstanten Wert enthält . Nach der Initialisierung können wir den Wert nicht mehr ändern.

final a = 5;
// Uncommenting below statement will give compilation error.
// Because a is declared as final.
// a = 6;

Alle unten genannten Aussagen sind akzeptabel.

// Without type or var
final a = 5;
// With a type
final int b = 5;
// With var
final var c = 6;

Kann einen Laufzeitwert zuweisen .

// 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;

Die endgültige Variable auf Klassenebene muss in derselben Zeile initialisiert werden.

Class A {
    static final a = 5;
    static final b = DateTime.now();
}

Die endgültige Variable auf Instanzebene muss in derselben Zeile oder in der Konstruktorinitialisierung initialisiert werden. Der Wert wird beim Erstellen des Objekts gespeichert.

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);
}

Zuweisen einer Liste .

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()];
Mahendran Sakkarai
quelle
20

Erweiterung der Antwort um @Meyi

  • Die endgültige Variable kann nur einmal festgelegt werden und wird beim Zugriff initialisiert (z. B. aus dem folgenden Codeabschnitt, wenn Sie biggestNumberOndicenur den Wert von verwenden, wird der Wert initialisiert und der Speicher zugewiesen).
  • const ist intern endgültig, aber der Hauptunterschied besteht darin, dass seine Kompilierungszeitkonstante, die während der Kompilierung initialisiert wird, auch wenn Sie seinen Wert nicht verwenden, initialisiert wird und Speicherplatz beansprucht.

  • Variablen aus Klassen können endgültig, aber nicht konstant sein. Wenn Sie eine Konstante auf Klassenebene wünschen, machen Sie sie statisch const.

Code:

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;
}
Faisal Naseer
quelle
2
Ich denke, ein besserer Weg, um die Frage zu stellen, ist, wann man die Laufzeitinitialisierung der Kompilierungszeitinitialisierung vorzieht ...
Faisal Naseer
und dafür können Sie @Meyi Antwort konsultieren und auch den Link des Artikels von seinem Beitrag besuchen, es ist wunderbar :)
Faisal Naseer
2

Beides finalund constverhindern, dass eine Variable neu zugewiesen wird (ähnlich wie finalin Java oder constin JavaScript).

Der Unterschied hängt damit zusammen, wie Speicher zugewiesen wird. Der Speicher wird zur finalLaufzeit für eine constVariable und zur Kompilierungszeit für eine Variable zugewiesen . Der finalModifikator sollte am häufigsten verwendet werden, da viele Programmvariablen keinen Speicher benötigen, da die Programmlogik nicht verlangt, dass sie initialisiert werden. Mit einer constVariablen sagen Sie dem Computer im Grunde: "Hey, ich brauche Speicher für diese Variable im Voraus, weil ich weiß, dass ich ihn brauchen werde."

Wenn Sie sie auf diese Weise betrachten, ist es einfacher, Unterschiede in ihrer syntaktischen Verwendung zu verstehen. Hauptsächlich, dass afinal Variable Instanzvariable sein kann, a constjedoch eine staticVariable in einer Klasse sein muss. Dies liegt daran, dass Instanzvariablen zur Laufzeit erstellt werden und constVariablen per Definition nicht. Daher müssen constVariablen in einer Klasse sein static, was einfach bedeutet, dass eine einzelne Kopie dieser Variablen in einer Klasse vorhanden ist, unabhängig davon, ob diese Klasse instanziiert ist.

In diesem Video wird es ziemlich einfach aufgeschlüsselt: https://www.youtube.com/watch?v=9ZZL3iyf4Vk

Dieser Artikel geht tiefer und erklärt einen sehr wichtigen semantischen Unterschied zwischen den beiden, dh finalmodifiziert Variablen und constmodifiziert Werte, was im Wesentlichen darauf hinausläuft, nur constWerte initialisieren zu können, die zur Kompilierungszeit ableitbar sind.

https://news.dartlang.org/2012/06/const-static-final-oh-my.html

Halten Sie das Zentrum gedrückt
quelle
2

final und const in Dart sind verwirrend für das Niveau, das wir denken, dass beide gleich sind.

Lassen Sie uns ihre Unterschiede sehen:

PS Ich habe Bild anstelle von Text eingefügt, da ich die Informationen im Stackoverflow .md-Format nicht einfach tabellieren konnte.

Erluxman
quelle
1

Wenn Sie kommen C++dann constin Dartist constexprin C++und finalin Dartist constin C++.

Das Obige gilt nur für primitive Typen. In DartObjekten sind markierte Objekte finaljedoch in Bezug auf ihre Mitglieder veränderbar.

Moshe Rabaev
quelle
2
Art von. Ich denke, man könnte dies für primitive Typen sagen, aber nicht für Objekte. constIn C ++ wird fast immer verwendet, um anzugeben, dass ein Objekt nicht durch eine bestimmte Referenz oder einen bestimmten Zeiger veränderbar ist. finalin Dart verhindert nicht, dass das Objekt durch diese Variable mutiert wird.
Jamesdlin
0

Sie können nicht eine Initialisierung constmit ein final. Zum Beispiel :

  final myConst = 1;
  const myFinal = 2;

  final a = myConst; // possible
  final b = myFinal; // possible
  const c = myConst; // this is not possible
  const d = myFinal; // possible
Jéwôm '
quelle
0

Wann soll welches Schlüsselwort verwendet werden?

Ein einfaches Beispiel für beide: Verwenden Sie final: Wenn Sie nicht wissen, welchen Wert es beim Kompilieren hat. Wenn Sie beispielsweise Daten von einer API abrufen müssen, geschieht dies, wenn Sie Ihren Code ausführen.

Verwenden Sie const: Wenn Sie sicher sind, dass ein Wert beim Ausführen Ihres Codes nicht geändert wird. Zum Beispiel, wenn Sie einen Satz deklarieren, der immer gleich bleibt.

https://itnext.io/difference-between-const-and-final-in-dart-78c129d0c573

Faisal Ahmed
quelle