Notice
Recent Posts
Recent Comments
Link
«   2025/06   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
Tags
more
Archives
Today
Total
관리 메뉴

kym8821 님의 블로그

한 페이지로 공부하는 Dart 기초 - 타입과 함수 본문

Dart

한 페이지로 공부하는 Dart 기초 - 타입과 함수

kym8821 2025. 1. 8. 16:00

기본 타입

모든 타입은 Object 클래스의 자식 클래스이다.

Dart의 타입들은 원시 타입이 없고 모두 참조 타입이다.

그 중 문자열, 정수, 논리값, 실수 타입은 간단하게 알고 넘어가자

  • String : 문자열
  • bool : 논리값 (true와 false만을 가짐)
  • int : 정수
  • double : 실수
  • num : 정수 및 실수 (int와 double의 부모 클래스)

간단하지만 매우 중요한 타입들이고, 가장 많이 사용되는 타입들이다.

다양한 메서드들을 지원해주지만, 지금은 각 타입들이 어떤 의미를 갖는지만 알고 넘어간다.

 

String Interpolation

어려운 단어를 사용했지만, 간단히 말해서 문자열 포멧팅이다.

사용법은 아래와 같이 ${변수 | 수식 | 함수호출 | etc} 꼴로 사용하면 된다.

int func(){
  return 3;
}

void main() {
  var result = 3;
  var stringFormatVariable = "result must be 3 : ${result}";
  var stringFormatExpression = "result must be 3 : ${1+2}";
  var stringFormatFunction = "result must be 3 : ${func()}";
  print(
    stringFormatVariable==stringFormatExpression && 
    stringFormatVariable==stringFormatFunction
  ); // res : true
}

동일하게 세 문자열 모두 "result must be 3 : 3" 이라는 결과가 나온다. 

 

List

일련의 자료를 순서대로 저장하는데 사용하는 타입이다.

List<type>을 활용한 명시적 타입 지정 방식과, var를 활용한 타입 추론 방식이 있다

void main(){
  var listByVar = [1,2,3,4,5]; // var을 활용한 int 리스트
  var multiTypeListByVar = [1,2,3,4, "String"]; // var을 활용한 Object 리스트
  List<int> listByType = [1,2,3,4,5]; // List<type>을 활용한 int 리스트
  List<Object> multiTypeListByType = [1,2,3,4, "String"]; // List<type>을 활용한 Object 리스트
}

만약 리스트에 여러 타입의 값을 저장하고 싶다면, 최상위 부모 타입인 Object를 사용하면 된다.

 

List는 여러 메서드를 지원해주지만, 지금은 선언 방법만 알아봤다.

지금부터는 collection if와 collection for이라는 독특한 Dart 문법에 대해서 알아보자

List의 collection if

특정 조건의 성립 여부에 따라서 값을 추가하려면 어떻게 해야할까?

기본 문법을 활용하면 if문을 활용하여 아래와 같이 할 수 있다.

void main(){
  int target = 5;
  List<int> list = [1, 2, 3];
  if(target%2 != 0){
    list.add(4);
  }
  print(list);
}

조건문이 참인 경우에 list의 맨 뒤에 4를 추가해주는 방식으로 동작한다.

 

Dart는 collection if 문법을 통해 보다 간결한 코드를 작성할 수 있다.

void main() {
  int target = 5;
  List<int> list = [
    1, 
    2, 
    3,
    if(target%2!=0) 4,
  ];
  print(list);
}

list 안에 조건문을 작성하였고, 해당 조건문이 참일 때 값을 추가해준다.

이러한 문법을 collection if 문법이라고 부른다. 당연히 조건문은 리스트 중간에 들어가도 된다.

List의 collection for

여러개의 값들을 리스트에 넣어주기 위해서는 반복문을 사용하는 것이 일반적이다.

아래는 그 예시이다.

void main() {
  List<int> list = [];
  for(int i=0; i<5; i++){
    list.add(i);
  }
  print(list);
}

반복문을 돌면서 0부터 5까지의 값을 리스트에 넣어주었다.

 

Dart의 collection for 문법을 활용하면 보다 코드를 간결하게 만들어줄 수 있다.

void main() {
  List<int> list = [
    for(int i=0; i<5; i++) i
  ];
  print(list);
}

list 안에 반복문을 작성하였고, 반복 조건이 유효한 동안에 계속해서 값을 넣어준다.

이러한 문법을 collection for 문법이라고 부른다.

 

maps

파이썬의 딕셔너리와 같이, 키-값 꼴의 데이터를 저장한다.

Map<keyType, valueType>을 활용한 명시적 타입 지정 방식과, var를 활용한 타입 추론 방식이 있다.

List와 마찬가지로 일관되지 않은 타입의 값을 가져야 한다면, keyType 혹은 valueType에 Object 타입을 사용하면 된다.

void main() {
  Map<String, int> mapByType = {
    "apple":1,
    "bear":2
  };
  Map<String, Object> mapByMultiValueType = {
    "apple":1,
    "bear":"String"
  };
  var mapByVar = {
    "apple":1,
    "bear":2
  };
  var mapByMultiValueVar = {
    "apple":1,
    "bear":"String"
  };
  print(mapByType.runtimeType); // res : IdentityMap<String, int>
  print(mapByMultiValueType.runtimeType); // res : IdentityMap<String, Object>
  print(mapByVar.runtimeType); // res : IdentityMap<String, int>
  print(mapByMultiValueVar.runtimeType); // res : IdentityMap<String, Object>
}

var을 사용했을 때, 일관된 타입은 해당 타입으로 추론하고 일관되지 않은 타입은 Object로 추론하고 있다.

 

sets

집합을 나타내기 위해 사용하는 데이터 타입이다.

Set<type>을 활용한 명시적 타입 지정 방식과, var를 활용한 타입 추론 방식이 있다

집합이므로 중복을 허용하지 않고 Object를 활용하여 여러 타입을 저장할 수 있다.

 

typedef

typedef 키워드를 사용하면 특정 타입의 별칭을 지정해줄 수 있다.

Map<String, String>과 같은 긴 타입에 짧은 별칭은 지정해줄 수 있기에 효율적이다.

typedef mss = Map<String, String>;
void main() {
  mss a = {
    "a":"apple",
    "b":"bear"
  };
  print(a);
}

Map<String, String>에 mss라는 별칭을 부여했고, mss를 대신 사용해도 정상 동작하고 있다.

 

qq 연산자

어떤 값이 null인지에 따라서 다른 값을 반환 혹은 할당하는데 사용하는 연산자이다.

 

left ?? right 연산자는 left 값이 null이면, right 값을, null이 아니면 left 값을 반환한다.

void main() {
  var a = null;
  var b = 1;
  var c = a??b;
  print(c); // res : 1(=b)
  c = b??2;
  print(c); // res : 1(=b)
}

var c = a??b에서는 a가 null이므로 오른쪽 값인 b 값을 반환하고 있다.

c = b??2에서는 b가 null이 아니므로 왼쪽 값인 b를 반환한고 있다.

 

a ??= value 연산자는 a가 null일 때 value 값을 넣어준다.

void main() {
  var a=null;
  var b=1, c=2;
  a ??= c;
  b ??= c;
  print(a); // res : 2(=c)
  print(b); // res : 1(=b)
}

a??=c에서 a가 null이므로 c의 값인 2가 들어간다.

b??=c에서 b가 null이 아니므로 b의 값을 그대로 사용한다.

 

함수

다른 언어들과 마찬가지로 사용자 지정 함수를 생성할 수 있다.

아래와 같은 꼴로 함수를 선언한다. C++와 거의 동일하다.

returnType functionName(parameters...){
  logic;
  return valueOfReturnType;
}

 

예시를 들어보면 아래와 같다.

int getTwice(int number){
  return number*2;
}

void main(){
  print(getTwice(2)); // res : 4
}

정수 number를 입력받아서 2배로 반환하는 함수 getTwice를 선언했다.

 

위 함수와 같이 결과값을 반환하기만 하는 함수는 Dart 문법을 활용하여 보다 간단하게 바꿀 수 있다.

int getTwice(int number) => number*2;

void main(){
  print(getTwice(2));
}

위 함수의 =>는 return을 의미한다는 것을 알 수 있다.

 

마무리

타입과 함수는 예시를 통해 공부하는 것이 좋다고 생각하기에 요약하기 애매하다고 생각한다. 어떤 개념을 배웠는지만 간단하게 알고 넘어가자

  1. Dart의 모든 타입들은 참조 타입이고, 일반적으로 non-nullable이다.
  2. Dart의 모든 타입들은 Object 클래스의 자식들이다.
  3. "${변수 | 함수결과 | 수식}"을 통해 문자열 포멧팅이 가능하다.
  4. List는 연속적인 값들을 담을 수 있는 타입이다. 대괄호( [ ] )를 통해 나타내고 List<type>꼴로 사용할 수 있다.
  5. map은 키-값 꼴로 값을 저장할 수 있는 타입이다. 중괄호( { } )를 통해 나타내고 Map<keyType, valueType>꼴로 사용할 수 있다. 
  6. set은 집합을 나타내는데 사용한다. 중괄호( { } )를 통해 나타내고 Set<type>꼴로 사용할 수 있다.
  7. typedef을 통해서 타입 별칭을 지정할 수 있다.
  8. ?? 혹은 ??=와 같은 qq 연산자를 통해 특정 값이 null인지에 따라서 다른 값을 반환하거나 할당할 수 있다.
  9. 사용자 지정 함수를 생성할 수 있다. 함수 이름, 리턴타입, 파라미터 등을 지정해야 한다.