본문 바로가기

kotlin, java, android

[kotlin] Lists and arrays / Null safety

0.

elements가 중복가능하다

= ordering이 있다

= indexing이 가능하다

  set list array
ordering 및 indexing X O O
elements 중복 가능 여부 X O O

 

Lists

1.

list는 generic하다. (elements로 올 수 있는 자료형이 여러 종류이다.)

listOf() mutableListOf()
- immutable
- 한번 만들면 read-only다. (elements 추가, 제거, 변경 모두 불가)
- list의 default
- mutable
- elements의 추가, 제거, 변경 모두 가능하다.

예시로 만들어본 코드에 이상한 점이 보인다.

val 이라고 선언하였으니 이 변수는 변경 불가능한 것이 아닌가? 제거가 가능하다니?

설명하자면, myList라는 변수는 처음에 가리키게 된 list를 계속 가리켜야한다. 

갑자기 myList에 새로운 뭐 yourList 같은 list를 배정할 수는 없는 일이다.

하지만 list자체는 mutable로 만들었기 때문에 그 요소의 수정이 가능한 상황이다.ㅎㅎ

 


Arrays

1.

arrays의 가장 큰 특징은 array의 각 elements들을 연속된 저장공간(contiguous memory locations)에 저장한다는 점이다.

그래서 list와 달리, size가 고정된다.

array의 elements들은 mutable한데, 이것은 값의 변경이 가능하다는 것을 의미한다. (size고정 → 추가, 제거 불가능!)

 

 

2.

arrays도 generic하다.

 

 

3.

array를 만들고 싶다면 arrayOf()를 써야한다.

이런 식이다. (앞에서 배운 for문과 downTo도 같이 연습해보았다!ㅎㅎ히히)

 

 

4.

primitive data type의 arrays가 있다. ex) ByteArray, ShortArray, IntArray 등

이 경우에는 자연스럽게 generic하지 않다.

왜 이런 arrays가 있느냐면, memory optimization을 위해서라고 한다.

예를 들어 일반적인 arrays는 64bits를 차지할 텐데, (64bits registers of CPU 기준)

ByteArray는 8bits를 차지하는 식이다.

질문 : 아니 근데 kotlin에 primitive type 없다며...? 이건 또 뭐냐..


Null safety

1.

Null pointer exception(NPE)란 선언되었으나 대입되지 않은, 즉 variable에 값이 없을 때

runtime 도중 이 variable에 접근하면 발생하는 error다. (runtime error)

kotlin은 이 null point exception을 막고 null safety를 지키기 위하여

① val 사용

② null 로 초기화 불가능 (사실은 가능할 때도 있는데, 아예 nullable과 non-nullable로 구분해버림!)

의 2가지 방법을 사용한다.

java에는 존재하지 않는 kotlin 독창적 특징이라 할 수 있다.

 

 

2.

variables는 null로 초기화될 수 없다. (null로 초기화하는 코드를 작성하면 compile time error)

근데 또 딱 한가지 null로 초기화하는 방법이 있는데, (...ㅎ)

바로 nullable type으로 선언되는 경우이다.

이런식으로 선언하면 nullable string type이 되는 것!

 

 

3.

nullable type은 다음의 3가지 operator로만 method call이 가능하다.

ⓐ Safe call operator ?.

?. 는 nonono가 null일 때 null을 return, null이 아닐 때 length를 return한다.

 

ⓑ Not-null assertion operator !!

이 operator는 웃기게도 nonono가 null이면 NPE를 발생시킨다.

NPE가 싫어서 시작한 일들인데 이게 대체 어떻게 된 일일까?

kotlin에서는, 절대로 null값이 들어가지 않을 거라고 생각하는 부분에 이 operator를 사용하라고 조언한다.

어쨌든 NPE가 발생한 부분을 파악할 수 있다는 것은 장점일 것이다.

 

ⓒ Elvis operator ?:

직관적인 이해를 위하여 바로 예제를 보자.

우선 변수 x를 nullable type으로 선언하였다.

?:는 기호 왼쪽의 값이 null이면 기호 오른쪽의 값을 return, null이 아니면 그 왼쪽 값 자체를 return한다.

line 2에서는 x가 null이 아닌 "312"이기 때문에 x?.length = x.length, x.length가 null이 아닌 3이기 때문에 3이 최종 return되었다.

line 6에서는 x가 null로 바뀌었기 때문에(line 5) x?.length = null, ?:도 null을 만나 오른쪽의 -1을 최종 return하게 되었다.