다트의 "const"키워드와 "final"키워드의 차이점은 무엇입니까?


답변:


236

다트 웹 사이트에 게시물이 있으며 꽤 잘 설명되어 있습니다.

결정적인:

"최종"은 단일 할당을 의미합니다. 최종 변수 또는 필드 에는 이니셜 라이저가 있어야합니다 . 일단 값을 할당하면 최종 변수 값을 변경할 수 없습니다. final은 변수를 수정 합니다 .


상수 :

"const"는 다트에서 조금 더 복잡하고 미묘한 의미를 갖습니다. const 값을 수정 합니다 . const [1, 2, 3]과 같은 컬렉션을 만들 때와 const Point (2, 3)와 같은 객체를 새로 만들지 않고 만들 때 사용할 수 있습니다. 여기서 const는 객체의 전체 딥 상태가 컴파일 타임에 전적으로 결정될 수 있으며 객체가 고정되어 완전히 불변임을 의미합니다.

Const 객체에는 몇 가지 흥미로운 속성과 제한이 있습니다.

컴파일 타임에 계산할 수있는 데이터로 작성해야합니다. const 객체는 런타임에 계산해야 할 항목에 액세스 할 수 없습니다. 1 + 2는 유효한 const 표현식이지만 new DateTime.now ()는 아닙니다.

그것들은 깊이, 전 이적으로 불변입니다. 컬렉션이 포함 된 최종 필드가 있으면 해당 컬렉션을 계속 변경할 수 있습니다. const 컬렉션이 있으면 그 안에있는 모든 항목도 재귀 적으로 const 여야합니다.

그들은 정규화 됩니다. 이것은 일종의 문자열 인터 닝과 같습니다. 주어진 const 값에 대해 const 표현식이 몇 번 평가되는지에 관계없이 단일 const 객체가 만들어지고 재사용됩니다.


이것이 무엇을 의미합니까?

Const :
보유한 값이 런타임에 계산되면 ( new DateTime.now()예 :) const를 사용할 수 없습니다 . 그러나 컴파일 타임 ( const a = 1;)에 값을 알고 있으면 constover 를 사용해야합니다 final. const와 (와) 사이에 다른 두 가지 큰 차이가 final있습니다. 먼저을 사용 const하는 경우을 static const대신 로 선언해야합니다 const. 둘째, const컬렉션 이 있으면 그 안에있는 모든 것이에 const있습니다. final컬렉션 이 있다면 그 안에있는 모든 것이 아닙니다 final .

마지막은 :
final 이상 사용해야 const당신이 컴파일시에 값을 모르는 경우, 그것은 런타임에 잡고 / 계산됩니다. 변경할 수없는 HTTP 응답을 원하거나 데이터베이스에서 무언가를 가져 오거나 로컬 파일에서 읽으려면을 사용하십시오 final. 컴파일 타임에 알 수없는 뭐든지해야합니다 final이상 const.


그 존재의 모든 말한다면, 모두 constfinal재 할당 할 수 없지만 필드 final객체는 한 그렇지 않은 것처럼 const또는 final, (달리 재 할당 할 수 있습니다 const).


3
const 키워드는 컴파일 타임 상수를 나타내는 데 사용됩니다. const 키워드를 사용하여 선언 된 변수는 암시 적으로 최종 변수입니다.
Arun George

1
@Meyi, 때 사용해야 const언제 final? 이 수정 자의 유스 케이스를 알고 있습니까?
CopsOnRoad

4
@CopsOnRoad 당신은 다트
콘 스트

2
마지막 문장은 정말 잘 요약되어 있습니다. 고마워
Yster

const가 옵션이라는 것을 신경 써야합니까? 성능 향상이 실제로인지 될 수 있습니까?
CodeGrue

63

콘 스트

값이 알려져해야 컴파일 시간 , const birthday = "2008/12/26"
초기화 후에는 변경할 수 없습니다.


결정적인

에 알고 있어야 가치 런타임은 , final birthday = getBirthDateFromDB()
초기화 후에는 변경할 수 없습니다.


10
가장 쉽고 가장 좋은 설명.
Ankur Lahiry

1
이 하나를 사랑 :)
파이살 Naseer

43

@Meyi 및 @ faisal-naseer 답변을 통합하고 프로그래밍이 거의 없었습니다.

const :

const 키워드는 컴파일 타임 상수 값 을 저장하는 변수를 만드는 데 사용됩니다 . 컴파일 시간 상수 값은 컴파일하는 동안 일정한 값입니다 :-)

예를 들어 5컴파일 시간 상수입니다. 하지만 DateTime.now()이는 컴파일 타임 상수가 아닙니다. 이 메소드는 런타임에 라인이 실행되는 시간 을 리턴하므로 따라서 변수에 변수 DateTime.now()를 할당 할 수 없습니다 const.

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

같은 줄에서 초기화 해야합니다 .

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;

아래 언급 된 모든 내용은 허용됩니다.

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

클래스 레벨 const 변수 는 아래와 같이 초기화해야합니다.

Class A {
    static const a = 5;
}

인스턴스 레벨 const 변수는 불가능합니다 .

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

또 다른 주요 용도 const객체를 불변 으로 만드는 데 사용됩니다 . 클래스 객체를 불변으로 만들려면 const 키워드를 생성자함께 사용하고 아래에 언급 된 것처럼 모든 필드를 최종으로 만들어야 합니다.

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

const 키워드를리스트에 사용할 수 있습니다 .

const a = const []- 객체 목록을 포함하는 것으로 a 초기화constconst 된 변수 (즉, 목록에는 컴파일 시간 상수 및 불변 객체 만 포함되어야 함). 따라서 다른 목록 으로 할당 할 수 없습니다a .

var a = const []- 목록 객체 를 포함하는 것으로 a 초기화varconst 된 변수 입니다. 따라서 변수에 다른 목록을 할당 할 수 있습니다a .

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 a = 5;
// Uncommenting below statement will give compilation error.
// Because a is declared as final.
// a = 6;

아래 언급 된 모든 내용은 허용됩니다.

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

런타임 값할당 할 수 있습니다.

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

클래스 레벨 최종 변수 는 동일한 행에서 초기화되어야합니다.

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

인스턴스 레벨 최종 변수 는 동일한 행 또는 생성자 초기화에서 초기화되어야합니다. 객체가 생성 될 때 값이 메모리에 저장됩니다.

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

목록 할당 .

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

@Meyi의 답변 확장

  • 최종 변수는 한 번만 설정할 수 있으며 액세스 할 때 초기화됩니다 (예 : 아래 코드 섹션에서 값만 사용하면 값 biggestNumberOndice이 초기화되고 메모리가 할당 됨).
  • const는 본질적으로 내부적이지만 가장 큰 차이점은 컴파일 시간 상수는 컴파일하는 동안 초기화되는 값이며, 값을 사용하지 않아도 초기화되고 메모리에 공간을 차지한다는 것입니다.

  • 클래스의 변수는 최종적이 될 수 있지만 상수는 아니며 클래스 수준에서 상수를 원하면 정적 const로 만듭니다.

암호:

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
질문을하는 더 좋은 방법은 컴파일 시간 초기화보다 런타임 초기화를 선호하는 것입니다 ....
Faisal Naseer

그리고 당신은 자신의 게시물의 멋진 :)에서 기사의 링크를 방문 할 수도 @Meyi 응답을 참조 할 수 있습니다
파이 Naseer

2

모두 finalconst재 할당되는 변수 방지 (방법과 유사한 final자바 작품이나 방법을 const자바 스크립트의 작품).

차이점은 메모리 할당 방법과 관련이 있습니다. 메모리는 final런타임에 const변수 및 컴파일 타임에 변수에 할당 됩니다. final그들을 초기화하는 프로그램 로직을 호출하지 때문에 많은 프로그램 변수가 메모리를 필요로하지 않기 때문에 수정, 더 일반적으로 사용되어야한다. const변수를 사용하면 기본적으로 컴퓨터에 "이 변수가 필요하다는 것을 알기 때문에이 변수에 대한 메모리가 필요합니다"라고 말합니다.

이런 식으로 생각하면 구문 사용법의 차이점을 더 쉽게 이해할 수 있습니다. 주로 final변수는 인스턴스 변수 일 수 있지만 a conststatic클래스 의 변수 여야합니다 . 이는 인스턴스 변수가 런타임에 생성되고 const변수 (정의에 따라)가 아니기 때문입니다. 따라서 const클래스의 변수는이어야합니다 static. 즉, 해당 클래스의 인스턴스화 여부에 관계없이 해당 변수의 단일 사본이 클래스에 존재한다는 것을 의미합니다.

이 비디오는 상당히 간단하게 설명합니다 : https://www.youtube.com/watch?v=9ZZL3iyf4Vk

이 기사는 더 깊이 들어가서 두 final변수 사이의 매우 중요한 의미 론적 차이를 설명합니다. 즉 변수를 const수정하고 값을 수정합니다. 본질적으로 const컴파일 타임에 파생 될 수있는 값만 초기화 할 수 있습니다.

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


2

finalconst 다트에 우리가 그들 모두가 같은 생각 수준으로 혼동된다.

차이점을 보자.

추신 : 나는 정보를 Stackoverflow .md 형식으로 쉽게 표로 만들 수 없었기 때문에 텍스트 대신 이미지를 포함시켰다.


1

당신이에서 오는 경우 C++다음 constDart있습니다 constexprC++final있는 Dart것입니다 constC++.

위의 형식은 기본 형식에만 적용됩니다. 그러나 Dart표시된 개체 final는 멤버 측면에서 변경할 수 있습니다.


2
일종의. 기본 유형에 대해서는 말할 수 있지만 객체에는 말할 수 없다고 생각합니다. constC ++에서 거의 항상 특정 참조 또는 포인터를 통해 객체를 변경할 수 없도록 지정하는 데 사용됩니다. finalDart에서는 객체가 해당 변수를 통해 변형되는 것을 막지 않습니다.
jamesdlin

0

을 (를) const사용하여 초기화 할 수 없습니다 final. 예를 들면 다음과 같습니다.

  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

언제 어떤 키워드를 사용합니까?

둘 다에 대한 간단한 예 : final 사용 : 컴파일 타임에 값이 무엇인지 모르는 경우. 예를 들어 API에서 데이터를 가져와야하는 경우 코드를 실행할 때 발생합니다.

const 사용 : 코드를 실행할 때 값이 변경되지 않을 것이라고 확신하는 경우. 예를 들어, 항상 같은 문장을 선언 할 때.

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

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.