Apa perbedaan antara kata kunci “const” dan “final” di Dart?

173

Apa perbedaan antara constdan finalkata kunci di Dart?

Ishmal Ijaz
sumber
1
Berikut adalah beberapa detail tentang const: stackoverflow.com/questions/51576209/… dan explonation sederhana ke finalkonstan (tidak dapat menetapkan ulang atau menetapkan sekali dibuat dengan kata kunci akhir) dan Anda harus menginisialisasi sekali.
Blasanka

Jawaban:

237

Ada posting di situs web dart dan itu menjelaskan dengan cukup baik.

Terakhir:

"final" berarti penugasan tunggal: variabel terakhir atau bidang harus memiliki penginisialisasi. Setelah diberi nilai, nilai variabel final tidak dapat diubah. final memodifikasi variabel .


Const:

"const" memiliki arti yang sedikit lebih kompleks dan halus di Dart. const memodifikasi nilai . Anda dapat menggunakannya saat membuat koleksi, seperti const [1, 2, 3], dan ketika membangun objek (bukan yang baru) seperti const Point (2, 3). Di sini, const berarti bahwa seluruh keadaan dalam objek dapat ditentukan sepenuhnya pada waktu kompilasi dan bahwa objek akan dibekukan dan sepenuhnya tidak dapat diubah.

Objek Const memiliki beberapa sifat dan batasan menarik:

Mereka harus dibuat dari data yang dapat dihitung pada waktu kompilasi. Objek const tidak memiliki akses ke apa pun yang Anda perlu hitung pada saat runtime. 1 + 2 adalah ekspresi const yang valid, tetapi DateTime.now () baru tidak.

Mereka sangat, secara abadi berubah. Jika Anda memiliki bidang terakhir yang berisi koleksi, koleksi itu masih bisa berubah. Jika Anda memiliki koleksi const, semua yang ada di dalamnya juga harus const, secara rekursif.

Mereka dikanonikalisasi . Ini adalah semacam string magang: untuk nilai const yang diberikan, objek const tunggal akan dibuat dan digunakan kembali tidak peduli berapa kali ekspresi const dievaluasi.


Jadi, apa artinya ini?

Const:
Jika nilai yang Anda miliki dihitung pada saat runtime ( new DateTime.now(), misalnya), Anda tidak dapat menggunakan const untuk itu. Namun, jika nilainya diketahui pada waktu kompilasi ( const a = 1;), maka Anda harus menggunakan constlebih dari itu final. Ada 2 perbedaan besar lainnya antara constdan final. Pertama, jika Anda menggunakan const, Anda harus mendeklarasikannya sebagai static constbukan hanya const. Kedua, jika Anda memiliki constkoleksi, semua yang ada di dalamnya ada di const. Jika Anda memiliki finalkoleksi, semua yang ada di dalamnya tidak final .

Final:
final harus digunakan lebih dari constjika Anda tidak tahu nilai pada waktu kompilasi, dan itu akan dihitung / diraih saat runtime. Jika Anda menginginkan respons HTTP yang tidak dapat diubah, jika Anda ingin mendapatkan sesuatu dari database, atau jika Anda ingin membaca dari file lokal, gunakan final. Apa pun yang tidak diketahui pada waktu kompilasi harus finalberakhir const.


Dengan semua yang dikatakan, keduanya constdan finaltidak dapat dipindahkan, tetapi bidang dalam finalobjek, selama mereka tidak constatau final, dapat dipindahkan kembali (tidak seperti const).

meyi
sumber
3
Kata kunci const digunakan untuk mewakili konstanta waktu kompilasi. Variabel yang dideklarasikan menggunakan kata kunci const secara implisit bersifat final.
Arun George
1
@ Mei, kapan kita harus menggunakan constdan kapan final? Apakah Anda tahu semacam kasus penggunaan untuk pengubah ini?
CopsOnRoad
4
@CopsOnRoad Anda bisa melihat video ini Dart Const vs Final
Lemuel Ogbunude
2
Kalimat terakhir itu benar-benar merangkumnya dengan baik. Terima kasih untuk itu.
Yster
Haruskah kita peduli bahwa const adalah pilihan? Apakah perolehan kinerja benar-benar dapat dipahami?
CodeGrue
64

Const

Nilai harus diketahui pada waktu kompilasi , const birthday = "2008/12/26"
Tidak dapat diubah setelah diinisialisasi.


Terakhir

Nilai harus diketahui saat run-time , final birthday = getBirthDateFromDB()
Tidak dapat diubah setelah diinisialisasi.

Haroun Hajem
sumber
11
Penjelasan termudah dan terbaik.
Ankur Lahiry
1
menyukai yang ini :)
Faisal Naseer
43

Jawaban @Meyi dan @ faisal-naseer terkonsolidasi dan Dibandingkan dengan sedikit pemrograman.

const:

Kata kunci const digunakan untuk membuat variabel untuk menyimpan nilai konstanta waktu kompilasi . Kompilasi nilai konstanta waktu adalah nilai yang akan konstan saat mengkompilasi :-)

Sebagai contoh 5adalah konstanta waktu kompilasi. Sedangkan DateTime.now()waktu kompilasi yang tidak konstan. Karena metode ini akan mengembalikan waktu ketika garis dieksekusi pada saat runtime. Jadi kita tidak bisa menetapkan DateTime.now()ke constvariabel.

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

Harus diinisialisasi pada baris yang sama .

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;

Semua pernyataan yang disebutkan di bawah ini dapat diterima.

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

Variabel tingkat kelas harus diinisialisasi seperti di bawah ini.

Class A {
    static const a = 5;
}

Variabel tingkat instans tidak dimungkinkan .

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

Penggunaan utama lain dari constdigunakan untuk membuat objek tidak berubah . Untuk membuat objek kelas tidak dapat diubah, kita perlu menggunakan kata kunci const dengan konstruktor dan menjadikan semua bidang sebagai final seperti yang disebutkan di bawah ini.

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

kita dapat menggunakan kata kunci const ke daftar .

const a = const [] - Variabel yang a diinisialisasi constyang berisi daftar constobjek (yaitu, Daftar harus hanya berisi konstanta waktu kompilasi dan objek yang tidak dapat diubah). Jadi kami tidak dapat menetapkan adengan daftar lain .

var a = const [] - Variabel yang a diinisialisasi sebagai varyang berisi daftar constobjek . Jadi kita bisa dapat menetapkan daftar lain ke variabela .

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

terakhir:

kata kunci akhir juga digunakan untuk membuat variabel untuk menyimpan nilai konstan . Setelah diinisialisasi, kami tidak dapat mengubah nilai.

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

Semua pernyataan yang disebutkan di bawah ini dapat diterima.

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

Dapat dapat menetapkan nilai runtime .

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

Variabel akhir tingkat kelas harus diinisialisasi dalam baris yang sama.

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

Variabel akhir level instance harus diinisialisasi dalam baris yang sama atau inisialisasi konstruktor. Nilai akan dimasukkan ke dalam memori saat objek dibuat.

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

Menetapkan daftar .

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
sumber
20

Memperluas jawaban dengan @Meyi

  • variabel akhir hanya dapat ditetapkan sekali dan diinisialisasi saat diakses. (misalnya dari bagian kode di bawah ini jika Anda menggunakan nilai biggestNumberOndicehanya maka nilai akan diinisialisasi dan memori akan ditetapkan).
  • Konst bersifat internal final tetapi perbedaan utamanya adalah konstanta waktu kompilasi yang diinisialisasi selama kompilasi bahkan jika Anda tidak menggunakan nilainya, konstitusi akan diinisialisasi dan akan memakan ruang dalam memori.

  • Variabel dari kelas dapat bersifat final tetapi tidak konstan dan jika Anda menginginkan konstanta di tingkat kelas, buatlah konstanta statis.

Kode:

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
sumber
2
Saya pikir cara yang lebih baik untuk mengajukan pertanyaan adalah kapan lebih suka inisialisasi runtime daripada inisialisasi waktu kompilasi ....
Faisal Naseer
dan untuk itu Anda dapat berkonsultasi @Meyi menjawab dan juga mengunjungi tautan artikel dari posting-nya indah :)
Faisal Naseer
2

Keduanya finaldan constmencegah agar variabel tidak dipindahkan (mirip dengan cara finalkerja di Jawa atau cara constkerja di JavaScript).

Perbedaannya berkaitan dengan bagaimana memori dialokasikan. Memori dialokasikan untuk finalvariabel saat runtime, dan untuk constvariabel saat kompilasi. The finalpengubah harus menjadi lebih umum digunakan, karena banyak variabel program tidak perlu memori apapun sejak logika program tidak akan meminta mereka untuk diinisialisasi. Denganconst variabel, Anda pada dasarnya memberi tahu komputer, "Hei, saya perlu memori untuk variabel ini di muka karena saya tahu saya akan membutuhkannya."

Memikirkan mereka dengan cara ini memudahkan untuk memahami perbedaan dalam penggunaan sintaksis mereka. Terutama bahwa suatu finalvariabel dapat berupa variabel instan, tetapi constharus merupakan staticvariabel pada suatu kelas. Ini karena variabel instan dibuat saat runtime, dan constvariabel - menurut definisi - tidak. Dengan demikian, constvariabel pada suatu kelas haruslah static, yang berarti secara sederhana bahwa satu salinan dari variabel itu ada pada suatu kelas, terlepas dari apakah kelas tersebut dipakai.

Video ini memecahnya cukup sederhana: https://www.youtube.com/watch?v=9ZZL3iyf4Vk

Artikel ini membahas lebih dalam dan menjelaskan perbedaan semantik yang sangat penting antara keduanya, yaitu finalmemodifikasi variabel dan constmemodifikasi nilai, yang pada dasarnya bermuara pada hanya mampu menginisialisasi constnilai yang dapat diturunkan pada saat kompilasi.

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

holding_the_center_down
sumber
2

finaldan constdi panah membingungkan ke tingkat kami pikir keduanya sama.

Mari kita lihat perbedaannya:

PS Saya memasukkan gambar sebagai ganti teks karena saya tidak bisa membuat tabulasi info dalam format Stackoverflow .md dengan mudah.

erluxman
sumber
1

Jika Anda datang dari C++kemudian constdi Dartadalah constexprdi C++dan finaldi Dartadalah constdi C++.

Di atas hanya berlaku untuk tipe primitif. Namun dalam Dartobjek yang ditandai finaldapat berubah dalam hal anggota itu.

Moshe Rabaev
sumber
2
Semacam. Saya pikir Anda bisa mengatakan ini untuk tipe primitif tetapi tidak untuk objek. constdi C ++ hampir selalu digunakan untuk menentukan bahwa suatu objek tidak bisa berubah melalui referensi atau pointer tertentu. finaldi Dart tidak mencegah objek dimutasi melalui variabel itu.
jamesdlin
0

Anda tidak dapat menginisialisasi constmenggunakan final. Sebagai contoh :

  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 '
sumber
0

Kapan menggunakan kata kunci yang mana?

Contoh sederhana untuk keduanya: Gunakan final: Jika Anda tidak tahu apa nilainya pada saat kompilasi. Misalnya, saat Anda perlu mendapatkan data dari API, ini terjadi saat menjalankan kode Anda.

Gunakan const: Jika Anda yakin suatu nilai tidak akan berubah ketika menjalankan kode Anda. Misalnya, ketika Anda mendeklarasikan kalimat yang selalu tetap sama.

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

Faisal Ahmed
sumber