지난번 연산자를 얘기할 때 변수에 대한 얘기를 간단하게 했다. 오늘은 플러터에서 사용하는 기본 변수 타입 및 활용에 대해 알아보고자 한다.
Dart에는 다음과 같은 기본 타입을 가진다.(더 있을 수 있음..ㅎ)
타입 | 예시 | 비고 |
---|---|---|
Object | Object data = 10; | 모든 데이터 타입의 슈퍼타입 |
num | num a = 10; | int형과 double형의 슈퍼타입 |
int | int a = 10; | 정수를 저장할 수 있는 타입 |
doule | double a = 10.3; | 실수를 저장할 수 있는 타입 |
bool | bool isDone = false; | true, false를 저장할 수 있는 불린 타입 |
String | String name = '남슈크림빵'; | 문자열을 저장할 수 있는 타입 |
var | var tmp = 24; | 초기화 후 타입 변경이 불가능한 미지정 타입 |
dynamic | dynamic tmp2 = 'tmpData'; | 초기화 후 타입 변경이 가능한 미지정 타입 |
List | var list = [1,2,3]; | 순서를 가지는 일반적인 콜렉션 |
Set | var colors = {'red', 'blue', 'yellow'}; | 순서와 중복이 없는 콜렉션 |
Map | var data = {'name': '남슈크림빵', 'age': 28}; | 연관된 키와 값을 가지는 오브젝트 |
num
, int
, double
타입다트에서 지원하는 숫자형 타입은 정수, 실수가 있으며 각각 int
, double
로 사용한다. 다른 언어와 다르게 다트는 멀티 플랫폼을 지원해야 하는 특성 상 short, float 형 등을 지원하지 않고 int와 double을 플랫폼에 맞게 적절하게 사용하는 것 같다. 다트의 숫자 사용 철학 등은 여기에서 확인해 보자.
int
와 double
은 num
타입을 슈퍼타입으로 가지고, num
은 다시 Object
를 슈퍼타입으로 가진다.
이를 통해 num
타입으로 지정한 변수는 int
혹은 double
타입으로 사용될 수 있음을 알 수 있다.
num
타입은 ceil
(소수점 자리수 올리기), abs
(절댓값), round
(반올림) 등의 메소드를 가지고 있으며, 그 외에 복잡한 함수는 dart:math
에서 사용 가능하다.
int age = 28; // int 형 변수 age에 28이라는 정수를 할당한다.
double height = 1.7; // double 형 변수 height에 1.7이라는 실수를 할당한다.
print('age: ${age}'); // age: 28
print('height: ${height}'); // height: 1.7
// int와 double을 모두 사용할 수 있는 num 형 변수 myVar에 int형 변수 age의 값을 할당한다.
// num타입 변수에 int 타입 데이터를 넣으면 해당 변수는 런타임에 int 타입으로 사용된다.
num myVar = age;
print('myVar: ${myVar}'); // myVar: 28
print('myVar.runtimeType: ${myVar.runtimeType}'); // myVar.runtimeType: int
// int와 double을 모두 사용할 수 있는 num 형 변수 myVar에 double형 변수 height의 값을 할당한다.
// num타입 변수에 double 타입 데이터를 넣으면 해당 변수는 런타임에 double 타입으로 사용된다.
myVar = height;
print('myVar: ${myVar}'); // myVar: 1.7
print('myVar.runtimeType: ${myVar.runtimeType}'); // myVar.runtimeType: double
String
타입숫자형 타입과 함께 친근한 문자열 타입이다. 다트의 문자열은 ''
혹은 ""
로 감싸진 데이터를 나타낸다. 또한 멀티라인을 변수에 할당하기 위해 ''' '''
를 사용할 수도 있다.
추가로 r'문자열'
처럼 사용하면 문자열 내에 사용한 이스케이프 시퀀스(escape sequence)를 작성된 그대로 보여준다.
String
타입도 클래스기 때문에 다른 언어들 처럼 split
, contains
, substring
등 다양한 메소드를 가지고 있다.
// 명시적 String 타입 title 변수에 ''로 감싸진 문자열을 할당한다.
String title = '오늘 저녁에는 치킨과 수제 소시지를 먹었어요.';
print('title: ${title}');
// title: 오늘 저녁에는 치킨과 수제 소시지를 먹었어요.
// var 타입 contents 변수에 ""로 감싸진 문자열을 할당한다.
var contents = "치킨은 생각보다 매콤했고\n소시지는 생각 이상으로 맛있었습니다.";
print('contents: ${contents}');
// contents: 치킨은 생각보다 매콤했고
//소시지는 생각 이상으로 맛있었습니다.
// var 타입 multiLineContents 변수에 ''''''로 감싸진 멀티라인 문자열을 할당한다.
var multiLineContents = '''다음에 지인이 근처 맛집을 물어보면
소개시켜주고 싶은 곳입니다.''';
print('multiLineContents: ${multiLineContents}');
// 다음에 지인이 근처 맛집을 물어보면
// 소개시켜주고 싶은 곳입니다.
// var 타입 rawString 변수에 r''로 감싸진 raw string 문자열을 할당한다.
var rawString = r'다음에 또 가고싶네요.\n이상입니다.';
print('rawString: ${rawString}');
// 다음에 또 가고싶네요.\n이상입니다.
Booleans
타입true
와 false
를 가질 수 있는 타입으로 bool
타입으로 사용한다. 일반적으로 조건식에 사용하며, 다양한 메소드들의 상태를 나타낼때 사용할 수도 있다. 추가로 다트는 type safety를 위해 다른 언어에서 암시적 bool 값을 지원하지 않는다. 예를 들어 변수의 값이 0이면 false로 인식하거나, 빈 문자열을 false로 인식하는 것을 방지하고 있다. 따라서 조건문 등에 명시적으로 bool 타입을 넣어주도록 주의하자.
// 명시적 bool 타입 isDone 변수에 false를 할당한다.
bool isDone = false;
print('isDone: ${isDone}'); // isDone: false
isDone = true;
print('isDone: ${isDone}'); // isDone: true
// var 타입 isDeleted 변수에 false를 할당하여 변수의 타입이 bool임을 알려준다.
var isDeleted = false;
print('isDeleted : ${isDeleted}'); // isDeleted: false
print('!isDeleted: ${!isDeleted}'); // isDeleted: true
List
타입많은 언어에서 배열이라고 칭하는 자료구조로 순서를 가지는 여러 데이터를 저장할 때 사용할 수 있다. 실제로 리스트는 List<type>
형태로 사용하지만, var를 이용한 추론 방법 또는 List variable = []
을 많이 사용하는 듯 하다.
variable[index]
형태로 각 인덱스에 접근할 수 있으며, 인덱스는 여타 언어처럼 0
부터 시작한다!add(data)
메소드를 통해 새로운 값을 리스트에 추가할 수 있다.removeAt(index)
메소드를 통해 해당 인덱스의 값을 제거할 수 있다.// var 타입을 이용하여 변수를 생성하였고, 할당할 데이터가 [1,2,3,4,5]이기 때문에 List<int>형으로 인식한다.
var intList = [1,2,3,4,5];
print('intList: ${intList}'); // intList: [1,2,3,4,5]
print('intList.length: ${intList.length}'); // intList.length: 5
// 명시적으로 int형 데이터를 담을 수 있는 리스트 intList2 변수
List<int> intList2 = [1,2,3];
print('intList2: ${intList2}'); // intList2: [1,2,3]
print('intList2.length: ${intList2.length}'); // intList2.length: 3
intList2.add(4); // 리스트에 새로운 값을 추가
print('intList2: ${intList2}'); // intList2: [1,2,3,4]
print('intList2.length: ${intList2.length}'); // intList2.length: 4
intList2.removeAt(0);
print('intList2: ${intList2}'); // intList2: [2,3,4]
print('intList2.length: ${intList2.length}'); // intList2.length: 3
// var 타입을 이용하여 변수를 생성하였고, 할당할 데이터가 ['one', 'two', 'three', 'four', 'five']이기 때문에 List<String>형으로 인식한다.
var stringList = ['one', 'two', 'three', 'four', 'five'];
print('stringList: ${stringList}'); // stringList: ['one', 'two', 'three', 'four', 'five']
print('stringList[0]: ${stringList[0]}'); // stringList[0]: one
List<String> stringList2 = ['one', 'two', 'three'];
print('stringList2: ${stringList2}'); // stringList2: ['one', 'two', 'three']
stringList[0] = 'zero';
print('stringList2: ${stringList2}'); // stringList2: ['zero', 'two', 'three']
Map
타입키와 값을 한 쌍으로 저장할 수 있는 데이터 타입으로, 파이썬 등의 언어에서 사용하는 딕셔너리와 같다고 보면 된다. 더 쉽게 얘기하면 {"key": "value"}
형태의 JSON같은 형태라고 생각하면 된다. 당연한 얘기지만, 맵에서 각 key는 고유해야 하며, 같은 키에 다른 값을 넣게되면 덮어씌워진다.
variable[key]
를 사용한다.addAll(data)
메소드를 사용하여 맵에 데이터를 넣을 수 있다.remove(key)
메소드를 사용하여 맵에서 데이터를 제거할 수 있다.variable.keys.toList()
, variable.values.toList()
로 키, 값만 가져와 리스트로 사용할 수 있다.Map dict = {
'name': '남슈크림빵',
'age': 28,
'height': 1.7
}; // Map<String, dynamic> 타입과 같음
print('dict: ${dict}'); // dict: {name: 남슈크림빵, age: 28, height: 1.7}
dict.addAll({'hobby': 'coding', 'sex': 'male'}); // addAll 메소드로 새로운 데이터를 추가할 수 있다.
print('dict: ${dict}'); // dict: {name: 남슈크림빵, age: 28, height: 1.7, hobby: coding, sex: male}
dict.remove('sex'); // remove 메소드로 데이터를 없앨 수 있다.
print('dict: ${dict}'); // dict: {name: 남슈크림빵, age: 28, height: 1.7, hobby: coding}
dict['age'] = 26; // key값으로 데이터데 접근 및 변경이 가능하다.
print('dict: ${dict}'); // dict: {name: 남슈크림빵, age: 26, height: 1.7, hobby: coding, sex: male}
var
, dynamic
타입위에서 var와 dynamic을 계속 사용하였는데, 정확한 차이가 어려울 수 있다. 쉽게 생각하면 var는 변수에 데이터가 할당되는 시점에 해당 데이터 타입으로 고정되는 가변 타입이고, dynamic은 할당된 이후에도 다른 타입의 데이터를 받아들일 수 있는 타입이다.
var name = '남슈크림빵';
print('name: ${name}'); // name: 남슈크림빵
// 코드를 실행했을 때 name 변수의 타입을 확인
print('name.runtimeType: ${name.runtimeType}'); // name.runtimeType: String
name = 28; // [ERROR] var로 선언한 변수가 String 타입으로 지정되었기 때문에 int형으로 변경할 수 없음
dynamic name2 = '남슈크림빵';
print('name2: ${name2}'); // name2: 남슈크림빵
// 코드를 실행했을 때 name2 변수의 타입을 확인하는 프로퍼티
print('name2.runtimeType: ${name2.runtimeType}'); // name2.runtimeType: String
name2 = 28; // dynamic 타입이기 때문에 변경이 가능하다.
print('name2: ${name2}'); // name2: 28
// 코드를 실행했을 때 name2 변수의 타입을 확인하는 프로퍼티
print('name2.runtimeType: ${name2.runtimeType}'); // name2.runtimeType: int