Dart'daki "const" ve "final" anahtar kelimeleri arasındaki fark nedir?


Yanıtlar:


237

Dart'ın web sitesinde bir yazı var ve oldukça iyi açıklıyor.

Final:

"final" tek atama anlamına gelir: bir son değişken veya alanın bir başlatıcısı olmalıdır . Bir değer atandığında, bir son değişkenin değeri değiştirilemez. final değişkenleri değiştirir .


Cephe:

"const", Dart'da biraz daha karmaşık ve ince bir anlama sahiptir. const değerleri değiştirir . Const [1, 2, 3] gibi koleksiyonlar oluştururken ve const Point (2, 3) gibi nesneler oluştururken (yeni yerine) kullanabilirsiniz. Burada const, nesnenin tüm derin durumunun tamamen derleme zamanında belirlenebileceği ve nesnenin dondurulacak ve tamamen değiştirilemeyeceği anlamına gelir.

Const nesnelerinin birkaç ilginç özelliği ve kısıtlaması vardır:

Derleme zamanında hesaplanabilen verilerden oluşturulmalıdır. Bir const nesnesinin çalışma zamanında hesaplamanız gereken hiçbir şeye erişimi yoktur. 1 + 2 geçerli bir const ifadesidir, ancak yeni DateTime.now () değildir.

Derin, geçişsiz değişmezler. Bir koleksiyon içeren bir son alanınız varsa, bu koleksiyon yine de değiştirilebilir. Bir const koleksiyonunuz varsa, içindeki her şey yinelemeli olarak da olmalıdır.

Onlar edilir canonicalized . Bu bir çeşit dize stajıdır: herhangi bir sabit değer için, sabit ifadelerin kaç kez değerlendirildiği önemli değil, tek bir sabit nesne oluşturulur ve yeniden kullanılır.


Peki, bu ne anlama geliyor?

Const: Sahip olduğunuz
değer çalışma zamanında hesaplanırsa ( new DateTime.now()örneğin), bunun için bir const kullanamazsınız. Ancak, değer compile time ( const a = 1;) öğesinde biliniyorsa, constüzerinde kullanmalısınız final. Arasında 2 diğer büyük farklılıklar vardır constve final. İlk olarak, kullanıyorsanız const, static constsadece değil de ilan etmelisiniz const. İkincisi, bir constkoleksiyonunuz varsa, içindeki her şey içeride const. Bir finalkoleksiyonunuz varsa, içindeki her şey değildir final .

Final: Derleme zamanında değeri bilmiyorsanız
finalkullanılmalıdır constve çalışma zamanında hesaplanır / yakalanır. Değiştirilemeyen bir HTTP yanıtı istiyorsanız, veritabanından bir şey almak istiyorsanız veya yerel bir dosyadan okumak istiyorsanız, kullanın final. Derleme zamanında bilinmeyen her şey finalbitmiş olmalıdır const.


O varlığın bütün sözlerimle, hem constve finalyeniden atanabilir, ancak bir alanlar finalnesne, yeter ki olmadıklarından constya final, (aksine yeniden atanabilir const).


3
Const anahtar sözcüğü, derleme zamanı sabitini temsil etmek için kullanılır. Const anahtar sözcüğü kullanılarak bildirilen değişkenler dolaylı olarak kesindir.
Arun George

1
@Meyi, ne zaman constve ne zaman kullanmalıyız final? Bu değiştirici için bir tür kullanım durumu biliyor musunuz?
CopsOnRoad

4
@CopsOnRoad bu videoyu inceleyebilirsiniz Dart Dart
Lemuel Ogbunude

2
Bu son cümle gerçekten çok iyi özetliyor. Bunun için teşekkürler.
Yster

Const'un bir seçenek olduğunu düşünmeli miyiz? Performans kazancı gerçekten algılanabilir mi?
CodeGrue

63

İnş

Değer en bilinmelidir derleme zamanında , const birthday = "2008/12/26"
başlatıldı sonra değiştirilemez olamaz.


final

En bilinmelidir Değer çalışma zamanında , final birthday = getBirthDateFromDB()
başlatıldı sonra değiştirilemez olamaz.


10
En kolay ve en iyi açıklama.
Ankur Lahiry

1
Bunu sevdim :)
Faisal Naseer

43

Konsolide @Meyi ve @ faisal-naseer cevapları ve az programlama ile karşılaştırılması.

const:

const anahtar sözcüğü, bir derleme zamanı sabit değerini depolamak için bir değişken oluşturmak için kullanılır . Derleme zamanı sabiti değeri derlenirken sabit olacak bir değerdir :-)

Örneğin 5bir derleme zaman sabiti. İken DateTime.now()hangi derleme zamanı sabiti değil. Çünkü bu yöntem , hattın çalışma zamanında yürütüldüğü zamanı döndürür . Yani DateTime.now()bir constdeğişkene atayamayız .

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

Olmalı aynı çizgide başlatıldı .

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;

Aşağıda belirtilen tüm ifadeler kabul edilebilir.

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

Sınıf düzeyinde sabit değişken aşağıdaki gibi başlatılmalıdır.

Class A {
    static const a = 5;
}

Örnek düzeyi sabit değişkeni mümkün değil .

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

Bir başka büyük kullanımı const, nesneyi değişmez kılmak için kullanılır . Bir sınıf nesnesini değişmez kılmak için const anahtar sözcüğünü yapıcı ile kullanmamız ve tüm alanları aşağıda belirtildiği gibi sonlandırmamız gerekir .

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

listeye const anahtar sözcüğünü kullanabiliriz .

const a = const [] - Nesnelerin listesini içerdiği şekilde a başlatılanconstconst bir değişken (yani, liste yalnızca derleme zaman sabiti ve değişmez nesneler içermelidir). Yani biz atayamıyorsanız can abaşka liste ile .

var a = const [] - Liste nesneleri içerdiği şekilde a başlatılmışvarconst bir değişken . Böylece değişkene başka bir liste atayabiliriza .

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

Final:

final anahtar sözcüğü, değişkeni sabit bir değer tutmak için de kullanılır . Başlatıldıktan sonra değeri değiştiremeyiz.

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

Aşağıda belirtilen tüm ifadeler kabul edilebilir.

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

Edebilmek için Can bir çalışma zamanı değeri atamak .

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

Sınıf seviyesi son değişkeni aynı satırda başlatılmalıdır.

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

Örnek düzeyi son değişkeni aynı satırda veya yapıcı ilklendirmesinde başlatılmalıdır. Nesne oluşturulduğunda değer belleğe alınır.

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

Bir liste atama .

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

20

Cevabı @Meyi ile genişletme

  • son değişken yalnızca bir kez ayarlanabilir ve erişildiğinde başlatılabilir. (örneğin biggestNumberOndiceyalnızca değerini kullanırsanız aşağıdaki değer başlatılır ve bellek atanır).
  • const doğada içsel olarak nihai olmakla birlikte temel fark derleme sırasında başlatılan derleme zaman sabitinin değerini kullanmasanız bile başlayacağı ve bellekte yer alacağıdır.

  • Sınıflardan değişken son olabilir ancak sabit olmayabilir ve sınıf düzeyinde bir sabit istiyorsanız statik sabit yapın.

Kod:

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

2
Soruyu sormanın daha iyi bir yolu, derleme zamanı başlatma sırasında çalışma zamanı başlatmayı tercih etmektir ...
Faisal Naseer

ve bunun için görevinden muhteşem :) gelen yazının bağlantıyı ziyaret do da @Meyi cevabı danışmak ve edebilirsiniz
Faysal Naseer

2

Hem finalve constyeniden atanmakta olan bir değişken önlemek (nasıl benzer finalJava eserleri ya da nasıl constJavaScript işleri).

Fark, belleğin nasıl tahsis edildiğiyle ilgilidir. Bellek, finalçalışma zamanında bir constdeğişken için ve derleme zamanında bir değişken için ayrılır . finalOnları başlatılması için program mantığı çağrı olmaz çünkü birçok programın değişkenleri herhangi bir bellek gerekmez çünkü değiştirici, daha yaygın olarak kullanılan olmalıdır. Bir constdeğişken ile temelde bilgisayara "Hey, bu değişken için ön belleğe ihtiyacım var çünkü ona ihtiyacım olacağını biliyorum."

Bunları bu şekilde düşünmek, sözdizimsel kullanımlarındaki farklılıkları anlamayı kolaylaştırır. Temelde bir finaldeğişkenin bir örnek değişkeni olabileceği, ancak bir sınıftaki constbir staticdeğişken olması gerektiği belirtilebilir . Bunun nedeni, örnek değişkenlerin çalışma zamanında yaratılması ve constdeğişkenlerin - tanım gereği - oluşturulmamasıdır. Bu nedenle, constbir sınıftaki değişkenler olmalıdır static, yani bu sınıfın somutlaştırılmış olup olmadığına bakılmaksızın sınıfta tek bir değişkenin tek bir kopyası var demektir.

Bu video oldukça basit bir şekilde parçalanıyor: https://www.youtube.com/watch?v=9ZZL3iyf4Vk

Bu makale daha derinlemesine inceliyor ve ikisi arasındaki çok önemli bir anlamsal farkı açıklıyor, yani finaldeğişkenleri constdeğiştiriyor ve değerleri değiştiriyor const.

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


2

final ve const dart içinde biz, her ikisi aynı olduğunu düşünüyorum seviyeye kafa karışıklığı yaratır.

Farklılıklarını görelim:

PS Bilgileri kolayca Stackoverflow .md biçiminde tablolama olamazdı gibi metin yerine dahil.


1

Eğer geliyorsa C++o zaman constiçinde Dartolduğu constexpriçinde C++ve finaliçinde Dartolduğu constiçinde C++.

Yukarıdakiler sadece ilkel tipler için geçerlidir. Ancak Dartişaretlenen nesnelerde finalüyeleri açısından değiştirilebilir.


2
Bir çeşit. Bence bunu ilkel tipler için söyleyebilirsiniz ama nesneler için değil. constC ++ 'da neredeyse her zaman bir nesnenin belirli bir referans veya işaretçi ile değiştirilemeyeceğini belirtmek için kullanılır. finalDart'da nesnenin bu değişken üzerinden mutasyona uğramasını engellemez.
jamesdlin

0

Bir ilklendirmeyecektir edebilir constbir kullanma final. Örneğin :

  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

0

Hangi anahtar kelime ne zaman kullanılır?

Her ikisi için de basit bir örnek: Final kullan: Derleme zamanında değerinin ne olacağını bilmiyorsanız. Örneğin, bir API'dan veri almanız gerektiğinde, bu kodunuzu çalıştırırken olur.

Const kullanın: Kodunuzu çalıştırırken bir değerin değiştirilmeyeceğinden eminseniz. Örneğin, her zaman aynı kalan bir cümle beyan ettiğinizde.

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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.