본문 바로가기
개발 팁 정리

[개발용어] Nullable(?)

by minhyeok.lee 2023. 2. 6.
반응형

Nullable = 너러블 타입, 널이 가능한, 값이 없을 수도 있는

단순히 null이 가능한 타입으로 명시해주는 방법으로 다양한 언어 및 프레임워크에서 ?로 제공한다.

 

변수

int? number;

변수 number가 가질 수 있는 값은 ?가 없다면 int 타입이지만 ?가 있다면 null도 가능하다.

 

클래스의 속성

export class User {
 name: string;
 team?: string;
}

?로 인해 여기서 name은 필수값(required), team은 선택값(optional)_(nullable하기 때문)이다.

 -> 실제로 NestJS에서 사용할 때는 위에 데코레이터(@)로 타입, 필수 여부 등이 명시적으로 작성되어 있다.

 

객체(json 타입)의 접근자

 변수 name은 user.name이 있을 경우 해당 값 없을 경우 홍길동이 되는 코드이다.

const name = user.name ?? "홍길동"

 L1:  Object 형태의 데이터를 외부로부터 받아올 때 아직 데이터가 오지 않았을 경우, 중간에 데이터 손실이 일어난 경우

 즉 user라는 객체를 읽지 못했을 경우 user.name에 접근 불가능하므로 에러가 발생한다.

 

 

위 상황같은 에러상황에서 다음과 같이 해결 가능하다.

const name1 = !!user ? user.name : "홍길동"
const name2 = user?.name ?? "홍길동"

L1. user가 있을 경우 name1은 user.name이고 없다면 "홍길동"

L2.user가 있을 경우 name2은 user.name이고 없다면 "홍길동"

 -> user.name을 'user 안에 name이 지금은 없으나 후에 들어올 것이다 이 값이 없는 것은 의도한 것이다.' 라는 확신이 있을 때 user?.name으로 변경해준다. 

 -> ?.으로 바꾸는 경우 조심해야하는 이유: ?를 붙이는 순간 그 값이 오지않아도 에러처리를 하지 않음. (개발자가 모른다)

 

이 두 개의 코드로직은 동작이 똑같다. (user.name은 필수 값이라고 하자)

name1에 user가 있을 때 user.name을 넣고 아니라면 홍길동을 넣어줘

name2에 user에 name의 값이 없을 수도 있는데 있으면 해당 이름, 없다면 "홍길동"을 넣어줘

 

'그렇다면 지금은 L1처럼 사용하는 것이 무조건 낫지 않나?' 라고 생각할 수 있지만 Object의 속성 depth가 높아졌을 경우,

즉 user라는 객체가 user.private.infomation.loginInfo.email까지 있을 때 위 코드를 L1처럼 사용한다면

let email = "이메일 정보 없음"
if(user) {
  if(user.private){
    ....
     if(user.private.information.loginInfo) email = user.private.information.loginInfo.email;
  }
}

조건 1. user가 존재하고

조건 2. user.private가 존재하고

조건 3. user.private.information이 존재하고

조건 4. user.private.information.loginInfo가 존재해야

조건 5. user.private.infomation.loginInfo.email에 접근할 수 있기 때문에

이를 조건으로 모두 건다면 객체의 속성 깊이 만큼의 조건이 매번 그 속성에 접근할 때 필요하기에 그건 좋은 방법이 아닐 것이다.

 

이때 ?를 사용한다면 

const email = user?.private?.infomation?.loginInfo?.email ?? "이메일 정보 없음"

위 코드처럼 사용할 수 있다.

 

 

?지만 아닌경우

 

1. 자바 와일드카드 

Collection<?> array = new ArrayList<string>();

 * 와일드카드<?>는 unknown type이다.

 

2. 삼항 연산자

let name = (x !== null) ? x : "null";

?는 연산자이다.

반응형

댓글