You are on page 1of 34

04

가장 많이 사용되면서
가장 혼동되는 내용

데이터 타입과 널 안전성


04-1 데이터 타입
04-2 상수 변수 – const, final
04-3 var 와 dynamic 타입
04-4 컬렉션 타입 – List, Set, Map
04-5 널 포인트 예외 관리하기
04-6 널 안전성 연산자
04-1 데이터 타입
 모든 변수는 객체
? 는 무슨 의미인가 ?
모르면 가리고 볼 것

다트의 타입 클래스
dartpad.dev

int? no = 10;
main() {
bool? data = no?.isEven;
no = null;
Object? obj = no;
print('$data, $no, $obj');
}
04-1 데이터 타입
문자열 표현하기
 문자열 데이터를 다룰 때는 String 클래스
 작은따옴표 ('hello') 나 큰따옴표 ("hello"), 또는 삼중 따옴표 ('''hello''', """hello""")
04-1 데이터 타입
문자열 표현하기

 두 문자열이 같은지 비교할 때는 다음처럼 == 연산자

 문자열에 동적인 결과를 포함하는 것을 문자열 템플릿

다음 코드의 결과 값은 ?
main() {
String str1 = 'hello1';
String str2 = 'hello'+'1';
print(str1==str2);

}
04-1 데이터 타입
형 변환하기
 변수가 모두 객체이므로 형 변환 type casting 도 자동으로 이뤄지지 않습니다 .
04-2 상수 변수 – const, final
컴파일 타임 상수 변수 - const
 컴파일 타임 상수 변수는 const 예약어로 선언
 const 변수는 톱 레벨이나 함수 내에 지역 변수로 선언할 수 있지만 , 클래스에 선언할 때는 static 변수로만 선언

매우 중요 !
어렵지만 , Quick Fix 를 사용하면
쉽다 . 그러나 , 원리는 알아야 한다 .

V3 부터 Sound Null Safe!


04-2 상수 변수 – const, final
런 타임 상수 변수 - final

 const 와 마찬가지로 값을 바꿀 수 없지만 , 초깃값을 대입하는 시점이 꼭 선언문이 아닐 수도 있습니다 .


04-2 상수 변수 – const, final
상수 변수와 문자열 템플릿
 const 예약어로 선언한 String 타입 상수 변수에 문자열 템플릿으로 값을 대입할 때는 템플릿 내부에도 컴파일 타임
상수를 사용

오류의 원인은 ?
컴파일 타임에서는 final 값을 알 수
없다 .
04-3 var 와 dynamic 타입
타입 유추 - var
 컴파일러가 해당 변수에 대입하는 값을 해석해 타입을 추측 초기값을 주면 타입이 고정된다 .
04-3 var 와 dynamic 타입
모든 타입 지원 - dynamic
 변수에 타입 대신 dynamic 을 사용하면 모든 타입의 데이터를 대입

Type-less Language 의 특징
04-4 컬렉션 타입 – List, Set, Map
리스트 타입
 List 는 데이터를 여러 개 저장하고 인덱스값으로 데이터를 이용하는 컬렉션 타입
 리스트를 선언하면서 초기화할 때는 대괄호 ([]) 를 이용

List 에 타입을 지정하지 않으면


모든 타입을 요소로 저장할 수 있다 .
04-4 컬렉션 타입 – List, Set, Map
리스트 타입
 특정한 타입의 데이터만 저장하는 리스트를 선언할 때는 데이터 타입을 제네릭으로 명시

Generic 이 무엇인가 ?

 데이터를 추가하거나 제거하려면 add() 나 removeAt() 함수를 이용


04-4 컬렉션 타입 – List, Set, Map
리스트 타입

 filled(), generate() 는 List 클래스에 선언된 생성자


 데이터를 몇 개 저장할지 크기를 지정
04-4 컬렉션 타입 – List, Set, Map
리스트 타입

 처음에 지정한 크기보다 많은 데이터를 저장할 수 있도록 허용하려면 filled() 생성자에 growable 매개변수를 true
로 지정
04-4 컬렉션 타입 – List, Set, Map
리스트 타입

 리스트를 초기화할 때 특정한 로직으로 구성된 데이터를 지정


04-4 컬렉션 타입 – List, Set, Map
집합 타입
 Set 은 List 와 마찬가지로 여러 건의 데이터를 저장하는 컬렉션 타입
 리스트와 차이가 있다면 중복 데이터를 허용하지 않습니다 .
04-4 컬렉션 타입 – List, Set, Map
맵 타입
 Map 은 여러 건의 데이터를 키와 값 형태로 저장하는 타입
ES6 에서의 객체 !
04-5 널 포인트 예외 관리하기
널 안전성이란 ?
 널 안전성 null safet 란 널 포인트 예외 NPE: null point exception 를 프로그램을 실행하기 전
 코드를 작성하는 시점에 점검하는 것을 의미
 NPE 발생 가능성을 컴파일러가 미리 점검해 주므로 널에 안전한 코드를 작성

자주 사용되기 때문에 매우 중요 !
어렵지만 , Quick Fix 를 사용하면
쉽다 . 그러나 , 원리는 알아야 한다 .
04-5 널 포인트 예외 관리하기
이런 것 없어도
널 허용과 널 불허 전혀 불편하지 않았는데
 변수를 선언할 때 널 허용 (Nullable) 과 널 불허 (NonNull) 로 구분 매우 번거롭다 .
 다트 언어에서 변수는 기본으로 널 불허로 선언
 널 허용으로 선언하려면 타입 뒤에 물음표 ? 를 추가
04-5 널 포인트 예외 관리하기
널 불허 변수의 초기화

 변수를 선언하면서 초깃값을 주지 않으면 자동으로 널로 초기화

Stack 변수에서는
int a1; 이 가능
04-5 널 포인트 예외 관리하기
var 타입의 널 안전성
 var 로 선언한 변수는 널 허용 여부도 대입하는 값에 따라 컴파일러가 자동으로 결정
 따라서 , var? 은 오류 발생
OK
04-5 널 포인트 예외 관리하기
var 타입의 널 안전성
04-5 널 포인트 예외 관리하기
dynamic 타입의 널 안전성

 dynamic 타입은 모든 타입의 데이터를 대입할 수 있으므로 널을 허용하는 Nullable 도 포함

의미가 없다고
지우라고 한다 .
04-5 널 포인트 예외 관리하기
널 안전성과 형 변환
자동형변환이 아니라
Superclass
 Nullable 은 NonNull 의 상위 타입 Subclass 간의 관계
04-5 널 포인트 예외 관리하기
널 안전성과 형 변환
상속관계가
성립되는 경우에만 가능
 다트에서 명시적 형 변환 연산자는 as
B1
D1 D2

B1 <-> D1
D1 <-> D2

Ex. int <-> String (X)


04-5 널 포인트 예외 관리하기
초기화를 미루는 late 연산자
 late 는 초기화를 미루는 연산자
04-6 널 안전성 연산자
널인지 점검할 때 - ! 연산자
 변수 이름 뒤에 ! 연산자를 추가하면 이 변숫값이 널일 때 런 타임 오류가 발생

두번째 호출의 경우 null 이 return


int b 는 int? 가 아니므로 오류 발생
이를 처리하기 위해 sum(20)! 으로 지정

수식 !
다음 문제를 해결하시오 .

String? str = "hello";


main() {
str.isEmpty;
}
? !
 null 조건 연산자 (null aware operator) -> ?.
 // null safety 적용 이후
String? notString = null;
print(notString?.length); // null 출력
 exp?.fn()
 If exp == null return null
else return exp.fn()
 즉 , 아 이건 널일 수도 있다는 걸 난 알고있어 !
 null 값 보증 연산자 (null assertion operator) => !
 notString!.length
 If notString == null throw Execption
 즉 , null 이어서 문제가 발생하더라도 내가 책임질께 !!
04-6 널 안전성 연산자 main() {
List<int>? list = [10, 20, 30];
print('list[0]: ${list[0]}');
멤버에 접근할 때 -?[] 연산자 list = null;
print('list[0]: ${list[0]}');
 널 허용 객체나 리스트의 멤버에 접근할 때는 ?. 나 ?[] 연산자를 사용 // 여기에서 ? 을 삭제하면 오류
}
04-6 널 안전성 연산자
값을 대체할 때 - ?? 연산자

 널 허용 변수가 널일 때 대체할 값을 지정하고 싶다면 ?? 연산자를 사용

간단 해석 :
data 가 null 인 경우에만 할당
04-6 널 안전성 연산자
값을 대입할 때 - ??= 연산자
 널 허용 변수에 널이 아닌 값만 대입하고 싶다면 ??= 연산자를 사용

data ??= 10;


간단 해석 :
data 가 null 이면 할당
요약
 Dart 에서 const 와 Sound Null Safe 는 필수적인 개념
 Sound Null Safe 는 실행시키기 전에 가능한 많은 오류를 발견하고 수정하려는 목적
 Const 의 목적은 실행속도 향상
 그러나 , 프로그램을 매우 번거롭게 한다 .
 오류 및 경고를 잘 읽어 보면 큰 도움이 된다 .
 그래도 사람이 매번 모든 경우의 수를 분석해서 수정하기가 매우 힘들다 .
 일반적으로 VSCode 의 Quick Fix 기능을 사용하면 매우 편리
 Quick Fix 에서 여러가지 대안을 주지만 ,
 이를 선택하려면 개념을 제대로 파악해야 한다 .
 다른 문법적 기능들
 chatGPT 에 물어보면 생산성 향상에 큰 도움이 된다 .
 본인이 코딩할 수 있는 능력이 있어야 원리를 알아야 제대로 물어볼 수 있다 .
 그래서 대학에서 원리를 공부하는 것이다 .

You might also like