fial과 const의 기본 개념은 한번 선언된 값을 변경되지 못하게 해달라는 의미를 가진다.
//일반적으로 우리가 사용할땐, 문자열 변수를 선언 후
String name = '이름';
//이렇게 값을 변경(재할당)하여 사용할 수 있다.
name = '이름2';
//하지만 선언 후, 할당한 값을 변경하지 못하게 하고 싶을 떈, 앞에 final을 붙여서 사용한다.
final String name = '이름';
//const도 마찬가지로 값을 변경하지 못하는 final과 같은 의미를 가진다.
const String name = '이름';
그런데 여기서 둘다 값을 변경하지 못하지만 어떤 차이가 있는지가 중요하다.
const의 경우 컴파일타임에 저장된다는 점과, final은 런타임에 지정된다는 점이 차이가 있다.
프로그래밍 언어가 기계어로 번역되어 실행되는 과정을 컴파일이라 하고, 이 과정을 컴파일 타임이라한다.
이 컴파일된 프로그램이 실행되는 과정이 런타임이라 한다.
무슨 의미인지는 아래 예제를 보면서 확인해 보자.
//실행한 결과값을 보면, 첫번째 라인의 값과 두번쨰 라인의 값이 1초정도 차이가 나는것을 확인할 수 있다.
//const는 첫번째 print의 값이고, final은 두번째 print의 값으로 예제를 들수 있는데,
//프로그램이 만들어 지기 전 컴파일되는 과정에서 값이 지정되어 버리는것은 첫번째 print. 즉 const이며
//컴파일 완료 후, 프로그램이 만들어진 후 실행되자마자 값이 지정되는 것이 두번쨰 print. 즉 final이다.
DateTime now = DateTime.now();
print(now);
Future.delayed(
Duration(milliseconds : 1000),
(){
DateTime now2 = DateTime.now();
print(now2);
}
);
실제 final과 const를 넣어서 예제를 다시 살펴보자.
//첫번째 print와 두번째 print의 값이 위 예제와 동일하게 1초간의 딜레이가 발생한것을 확인할 수 있다.
//이는 당연히 컴파일이 완료된 후, 런타임(프로그램 시작!)시에 값이 할당되어 출력되기 때문이다.
final DateTime now = DateTime.now();
print(now);
Future.delayed(
Duration(milliseconds : 1000),
(){
final DateTime now2 = DateTime.now();
print(now2);
}
);
//09.변수 정의 규칙의 대하여
void main() {
//1. 같은 이름의 변수를 사용하지 않는다.
String _name = '임의값1';
//아래 변수는 사용할 수 없다.
//이건 IDE에서도 제한한다.
//String _name = '임의값2';
//그래도 값을 쓰고 싶다면 새로 선언이 아닌 재할당은 가능하다.
_name = '임의값2';
//또한 타입을 다르게 해서 선언해도 안된다.
//이미 사용한 변수명 중복금지.
//int _name = 1;
/*
* 변수의 타입이 같던 다르던, 같은 이름의 변수는 선언할 수 없다.
* */
//2. 대부분의 프로그래밍 언어는 소문자로 변수선언을 한다.
int _name2 = 1;
//3. 여러개의 변수 이름을 이어서 하고싶다면?
//아래와 같이 선언해서는 안된다.
//String rain bow = 'color';
//4. 공백없이 붙여서 사용하며, 단어가 바뀌는 구간에 대문자로 변경하여
//두가지 의미를 가진 단어가 합쳐진것으로 친다. 암묵적인 룰
//낙타 표기법이라 한다.
String rainBow = 'color';
//5. 언더바를 먼저 사용할 수 있다.
//이 언더바를 사용한 변수는 주로 private변수 및 class에서 사용이 많이된다.
//나중에 다루겠음.
String _rainBow = 'color';
//6. 대문자로 시작하는 경우
//소문자로 시작한 name이 선언되어 있다고 해도, 사용가능하다.
//다른 변수로 인식은 하지만, 일반적으로 class에서 대문자로 시작하여
//사용하기 때문에, 추후 개발자들간에 업무에 있어서 혼동을 방지하기 위해
//대문자 시작은 최대한 사용하지 않도록 한다.
String Name = '이름';
}
관련 소스는 아래와 같이 첨부한다. (주석과 함께 읽어내려가면서 코드를 실행하고, 이해하는것이 좋다.)
void main() {
//08. Map 타입
//Map은 key value pair방식이다. (한쌍,짝)
//Map은 List의 대괄호와는 반대로 중괄호를 사용한다.
//콜론을 기준으로 왼쪽은 키, 오른쪽은 밸류로 인식한다.
//여러값을 넣고 싶으면 콤마를 기준으로 추가한다.
Map dictionary = {
'apple': '사과',
'banana' : '바나나',
'watermelon' : '수박'
};
print(dictionary);
//key값을 넣으면 원하는 value값을 추출할수 있다.
print(dictionary['apple']);
//이번에는 선언 후, 값을 추가하는 방법에 대해 알아보자.
Map dictionary2 = {};
print('------------');
print(dictionary2);
dictionary2.addAll({
'apple': '사과',
'banana' : '바나나',
'watermelon' : '수박'
});
//위와같이 선언 후에 값을 일괄로 할당할 수 있다.
print(dictionary2);
//만약 들어있는 값 중 특정값을 삭제하고 싶다면?
//아래와 같이 remove함수를 사용하여 삭제할 수 있다.
dictionary2.remove('apple');
print(dictionary2);
//그렇다면, 변경은 어떻게 할까?
//변경은 List와 같다. List에서 Index를 사용했지만
//Map은 Key값을 사용한다.
dictionary2['banana'] = '버내너';
//할당한 값대로 변경된것을 확인할수 있다.
print(dictionary2);
//List는 Index를 사용하지만, Map는 Key값을 사용한다는 것을 알수있다.
//이번에는 List에서 다뤘던 2가지 선언방법 중 new를 사용한 선언방법처럼
//Map도 new를 사용하여 선언해보자.
Map dictions = {};
Map distions2 = new Map();
Map dictions3 = new Map.from({
'apple' : '사과',
'banana' : '바나나'
});
//List처럼 .from 을 이용하여 할당도 가능하다.
print(dictions3);
//또한 이 Map으로 사용된 것을 List형태로 변경도 가능하다.
//toList앞에 Keys는 Map의 Key값만 List화 하라는 것을 의미한다.
print(dictions3.keys.toList());
//value만 프린트 하고 싶다면 어떻게 할까? Keys와 반대로.
print(dictions3.values.toList());
//위와같이 변경한 뒤부터는 List처럼 사용할수 있는것이다.
//지난 List에서는 안에 들어갈 값의 타입을 설정할수 있었다.
//Map도 가능하다.
Map<String, int> price = {
'apple' : 2000,
'banana' : 4000,
'watermelon' : 6000
};
//위와같이 지정을 할수 있다. 지정을 안해도 무방하지만
//지정을 하는것이 정확한 데이터의 종류와 개발을 위해서라도 타입을 지정하는게 좋다.
//정말 중요한것. Map에서의 Key는 절대적으로 유니크해야한다.
//무슨말이냐면, 이미 key값으로 apple이 들어있는 상태에서 또 apple에 다른값을 넣으면
//List와는 다르게 추가되지 않고, 덮어씌어진다.
//반드시 1개만 존재할수 밖에 없다는것을 명심할것.
}