본문 바로가기
Flutter/Dart의 정석

[Dart의 정석] Ch3.1. Dart의 Type System

by Couldi 2022. 5. 24.
반응형

22. 5. 24.

- Could -

이 글은 다트를 공부하고자 하는 모든 사람들을 위한 글이 아니다. 다트라는 언어의 전문가가 되기를 위한 사람들을 위한 글이기 때문에, 프로그래밍을 처음 공부하는 사람들이 보기에는 부적절할 수 있다. 프로그래밍의 초심자라면 본 블로그에 'Dart 입문'을 살펴보거나, 다른 컨텐츠를 찾아 공부하는 편이 더 나을 것이다.
가능한 이해하기 쉽고 일목요연하게 정리하고자 하지만, 다소 설명이 난해하거나 이해하기 어려울 수 있다. 그런 경우 댓글을 통해 궁금한 사항을 남겨두면 필자가 언젠가 보고 좀 더 상세한 설명을 덧붙일 수 있으니 많은 댓글을 바란다.
추가적으로 이 글은 Flutter(플러터)에 대해 다루지 않는다. Dart에 대한 내용만을 다룰 예정이다.

https://dart.dev/guides/language/type-system

 

The Dart type system

Why and how to write sound Dart code.

dart.dev

1. 정적(Static) 타입 언어와 동적(Dynamic) 타입 언어

프로그래밍 언어를 두가지로 구분하자고 하면, 정적(Static)타입 언어와 동적(Dynamic)타입 언어로 나누어 볼 수 있다. 이 둘의 차이를 이해하기 위해서는 컴파일과 런타임의 개념을 알아야하는데, 이걸 이해하기 위해서는 저급언어와 고급언어의 구분부터 이야기를 시작해야한다.

저급 언어 vs 고급 언어

프로그래밍 언어는 기본적으로 컴퓨터에게 명령을 내리기 위해 만들어진 언어이다. 컴퓨터와 사람 사이에 누가 더 이해하기 쉬운 언어인가에 따라 저급 언어와 고급 언어가 나뉘어진다. 이 둘은 절대적인 개념이 아닌 상대적인 개념으로, 사람이 이해하고 사용하기 쉬울 수록 고급언어, 컴퓨터가 이해하고 사용하기 쉬울수록 저급언어로 구분된다. 우리가 한번쯤 들어본 프로그래밍 언어는 대부분 고급언어에 속한다. 프로그래밍에 익숙치 않아 코드를 읽고 쓰는데 어려움을 겪는 사람들에게는 미안한 말이지만, 그게 사람들이 '이해하기 쉽게' 쓰여진 고급 언어이다. 일반적으로 Python, Java, C, C++, C#, Dart, JavaScript 등이 고급언어에 속하고, 기계어와 어셈블리어를 저급언어로 분류하지만 상대적인 개념이라는 것만 알아두자.

컴파일러(Complier)와 인터프리터(Interpreter)

앞서 프로그래밍 언어를 고급 언어와 저급언어로 구분했고, 고급언어는 사람이 이해하기 쉬운 언어라고 했다. 사람이 이해하기 쉬운 언어로 프로그래밍을 하면 컴퓨터 입장에서는 이해하기 어려운 언어라는 말이 된다. 이 문제를 해결하기 위해 나오는게 '컴파일러'와 '인터프리터'이다. 이 둘을 쉽게 설명하자면 우리가 작성한 코드를 컴퓨터가 알아먹기 쉽게 번역해주는 번역기이다.

이 둘은 번역하는 방식에서 차이를 보이는데, 컴파일러는 모든 코드를 한번에 번역하여 컴퓨터에게 전달하고, 인터프리터는 한줄씩 코드를 번역하여 전달하는 과정을 반복한다. 이 두가지 번역기 중에 어떤 번역기를 사용하느냐에 따라 언어가 가지는 특징이 생기는데, 이 차이의 경우는 구글링을 통해 알아보는 걸 권한다.

우리가 집중해야하는 건 Dart고 Dart는 컴파일러를 사용하는 프로그래밍 언어이다.

컴파일 타임(Complie Time)과 런타임(Run time)

앞서 고급언어를 저급언어로 번역해주는 번역기가 컴파일러라고 했다. 컴파일 타임은 고급언어를 저급언어로 번역하는 시점을 의미한다. 런타임은 컴퓨터가 저급언어로 번역된 코드를 받아 실행하는 시점을 의미한다.

정적(Static) 타입 언어와 동적(Dynamic) 타입 언어의 구분

정적 타입 언어와 동적 타입 언어의 구분은 타입(Type)이 결정되는 시점에 따른 구분이다. 여기서의 Type은 Data가 가지는 Type을 의미한다.

  • 정적(Static) 타입 언어 : 컴파일 시점에 데이터들의 타입을 확인한다. (e.g. Dart, Java, Kotlin, Swift)
  • 동적(Dynamic) 타입 언어 : 런타임 시점에 데이터들의 타입을 확인한다. (e.g. Python, JavaScript)

데이터가 가지는 타입을 어느 시점에 확인하느냐에 따라 언어의 구분이 바뀐다. Dart의 경우는 컴파일 언어이자, 정적 타입 언어로 컴파일 시점에 데이터 타입을 체크하는 언어다. 이 구분이 왜 중요한가 싶겠지만, 이 시점에 따라 언어의 특징이 생기게 된다. 

정적 타입 언어의 장점

  • 타입과 관련된 에러를 컴파일 시점에 발견할 수 있다.
  • 보다 안정적인 코드를 작성할 수 있다.
  • 보다 이해하기 쉬운 코드를 작성할 수 있다.

결론

  • Dart는 고급언어이다.
  • Dart는 컴파일 언어이다.
  • Dart는 동적 타입 언어이다.

이것저것 복잡한 설명을 가져다 붙였지만, 가장 중요한건 위의 결론에 따라 Dart가 가지는 특징이다. Dart는 데이터의 Type에 매우 민감한 언어이다. String, int, double, bool 등 앞서 데이터 타입에 대해 길게 설명한 이유이기도 하다. Dart는 각 데이터가 어떤 타입인지 꼭 명시해주어야하며, 이러한 특징으로 인해 보다 안정적인 프로그래밍을 가능하게 해준다. (타입에 자유로운 언어를 사용해왔던 개발자들에게는 다소 답답하게 느껴질 수도 있겠지만, 조금만 익숙해지고 나면 타입의 강제가 가져오는 편안함에 마음의 안정을 찾을거라  생각한다.)

2. var

JavaScript를 공부했었다면 한번쯤은 봤을 var이다. JavaScript에서 var를 사용해 변수를 정의하면 그 안에 아무타입의 데이터든 전부 넣을 수 있다. 일종의 아무거나 넣어도 된다는 변수의 선언이고, 이 var를 Dart 역시 지원한다. 

var name = 'James';
var age = 39;
var weight = 89.5;

위와 같은 형태로 변수를 선언 할 수 있다. 개인적으로 위와 같이 코드를 짜는 걸 매우 혐오하는 편이다. 다루어야 할 데이터 타입이 명확하다면 명확한 데이터 타입을 적어라. 아래와 같이 코드를 적는게 정신건강에 좋다. 아래처럼 코드를 작성하는걸 선호하는 많은 이유가 있지만 지금은 일단 넘어가자.

String name = 'James'
int age = 39;
double weight = 89.5;

 

앞서 Type을 다룰때 문자, 숫자, 진리값 등으로 나눠서 다뤘었는데, 만능으로 쓸수 있는 var 어떻게 가능한 것일까?

Dart는 컴파일언어이긴 하지만 똑똑한 언어라, Type inference라는 기능을 지원한다. 한글로 번역하면 '타입 추론'이라는 뜻이고, var 타입의 변수를 만들면, 안에 들어가는 데이터의 타입에 따라 타입을 추론해 컴파일시 타입을 지정해준다.

cf. Dart의 var는 JavaScript의 var와 다르다.
JavaScript에서 var로 변수를 만들면, 문자열을 넣었다가 숫자를 넣었다가 마음대로 바꿀 수 있다. 하지만 Dart의 경우, 컴파일 시점에 var로 선언한 변수의 타입이 정해지기 때문에 다른 타입의 데이터를 해당 변수에 넣으려고 하면 에러가 나게 된다.
var age = 39; // 컴파일 시점에 age라는 변수는 int 형으로 타입이 결정된다.
              //(이런걸 타입추론(type inference)이라고 부른다.)
age = 'thirtnine'; // int형 변수에 String을 넣으려고 하니 당연히 에러가 나게된다.​

 

3. final vs const

이 둘을 구분하는 건 중요하다.

https://couldi.tistory.com/33

 

[Dart] 12. final vs. const

21. 11. 5. - Could - 이 글은 프로그래밍 입문을 Flutter 때문에 Dart로 시작하는 사람들을 위한 글입니다. 프로그래밍 언어가 가지고 있는 기본 컨셉 자체를 Dart라는 언어를 통해 설명하고, 많은 분들이

couldi.tistory.com

위 링크에 설명해두었으니, 여기서 다시 언급하지는 않겠다.

 

4. dynamic

앞서 var로 변수를 만들면 컴파일 시점에 타입추론이 이루어지면서 다른 타입의 데이터를 변수에 담지 못하는 상황이 된다는 걸 배웠다. dynamic은 이런 문제를 해결해주는 녀석이다. 정말 아무거나 넣었다 뺐다 마음대로 할 수 있는 상자라고 생각하면 된다. dynamic은 JSON 형태의 데이터나 특정한 형태의 데이터를 주고 받을때 아주 유용하게 쓰이는 녀석이다. 그러나 남용하는 것은 금물이다. 꼭 필요한 곳에만 사용하는 녀석이라고 생각하자.

dynamic age = 39; // Dynamic으로 변수를 만들면,
age = 'thirtynine'; // 변수에 넣는 데이터 타입를 바꿔도 에러가 나지 않는다.
// 정말 다이나믹하다!

 


제언. Dart를 사용한다면...

  • var를 쓰지말자. JavaScript도 ES6 문법으로 넘어가면서 거진 버린 녀석이 var이다. 쓰지말자. 써야할 이유가 없다.
  • dynamic은 꼭 필요한 곳에만 쓰자. 남용하지 말자.

위와 같이 이야기하는건 프로그램의 성능을 위한 것도 있지만, 데이터 타입을 구체적을 명시하는 게 프로그래밍에서 가져다 주는 이점이 더 크기 때문이다. 잠깐의 편안함 때문에 타입을 소홀하게 생각하지 말자.

반응형

댓글