본문 바로가기
언어/Dart

Dart 시작하기!

by 개발짜 2024. 10. 8.

Dart 는 Flutter 를 사용하기 위한 언어이며 이번에 배워볼 언어이다.

여태 Java 를 자주 사용했으니 Java 를 기준으로 차이점을 두고 써 보겠다.

 


변수 선언

Var

Dart 는 Java 와 달리 변수의 타입을 미리 지정하지 않아도 컴파일러 단에서 타입 추론(Type Inference) 를 해서 처리한다.

타입 추론은 변수에 할당한 값을 보고 String 이나 int 등의 타입일 것이라고 추론하는 것이다.

var 로 지정한 변수는 다시 할당할 수 있다는 특징을 가진다.

다음과 같이 사용 가능

void main() {
    var name = '홍길동';
    var age = 10;
}

 

위에 코드를 보자면 name 은 String 타입이고 age 는 int 타입이라고 Dart 에서 타입 추론을 하게 된다.

 

Dynamic Type

dynamic 타입은 여러가지 타입을 가질 수 있는 변수에 사용한다.

여러가지 타입이라니 Java 나 C 를 사용할 때는 상상할 수 없었던 것인데, 실제로 자주 사용하지는 않다고 한다.

다음과 같이 사용이 가능하다.

void main() {
    dynamic name;
    name = '홍길동';
    name = 10;
    name = true;
 }

String 타입인줄 알았던 'name' 이 int 나 bool 타입으로도 사용이 가능하다는 게 좀 더 기괴한 느낌인데, 컴파일에서 알아서 처리해준다니 신기할 따름이다.

 

Nullable

Java 사용하면서 null 은 아주 위험한 값인데 dart 에서는 null safety 한 언어다.

최근에 나오는 언어는 nullable 하게 만드는 것이 트렌드같다.

dart 에서는 기본적으로 모든 변수가 non-nullable 이지만 다음과 같이 '?' 를 타입 뒤에 붙여두면 nullable 하게 사용이 가능하다.

지금은 nullable 한 변수를 어떻게 사용하는지 감이 안 잡히지만 일단 킵고잉

void main() {
    String? name = '길동';
    name = null;
 }

 

Final

한 번 지정하면 변수에 재할당이 불가능하게 지정하는 타입이다.

final 은 프로그램 실행, 즉 런타임 시점에서 초기화가 되기 때문에 나중에 값을 할당해줘도 된다.

void main() {
    final name = '길동';
    final int age = 10;
    // 이건 불가능한 코드
    name = '춘향';
 }

 

name 처럼 자세한 타입 지정을 안해도 되고, age 처럼 타입 지정을 하면서 final 이라고 선언할 수 있다.

 

Late

이름 그대로 나중에 할당이 가능하게 해주는 타입인데, final 로 선언한 타입에도 가능하다.

late 는 NonNullable 한 특징을 갖고있다.

void main() {
    late final name;
    // 블라블라 코드~~
    name = '춘향'; // 가능
    name = '길동'; // 하지만 두 번 할당은 불가능
 }

 

Constant

constant 는 상수라는 뜻이며 final 과 아주 흡사하다.

한 번 지정하면 재할당이 불가능한데, 차이점은 const 는 컴파일할 때 알고있는 값을 사용해야 한다는 점이다.

void main() {
    const v = 'variable'; // 가능
    const api = somethingApi(); // 불가능
 }

 


 

데이터 타입

 

기본적인 데이터 타입(숫자/문자/Boolean)

숫자형

Int

정수형

void main() {
    int a = 10;
}

 

Double

실수형

void main() {
    double a = 10.1;
}

 

Num

int 와 double 의 상위 클래스이기 때문에 정수형, 실수형 둘 다 사용할 수 있다.

void main() {
    num a = 10;
    num b = 10.1;
}

 

String

Java 랑 똑같은 문자열 String 타입이다.

void main() {
    String a = "string 값";
    String b = 'string 값';
    String abc = """이렇게
                줄바꿈도
                가능함""";
}

 

Boolean

참/거짓 값만 있는 타입

void main() {
    Bool a = true;
    Bool b = false;
}

 

Lists

기본적인 배열인데 정말 신기한 점은 배열 초기화할 때 if 문을 넣을 수 있다는 게...!! 신세계

다음과 같은 문법을 Collection if 라고 한다.

void main() {
   var giveMeFive = true;
   var numbers = [1, 2, 3, 4, if (giveMeFive) 5];
   print(numbers);
 }
 결과 
 [1, 2, 3, 4, 5]

 

String Interpolation

text 에 변수를 추가하는 방법인데 Java 의 String format 같은 느낌이다. $ 뒤에 원하는 변수를 추가해서 사용한다.

$ 뒤에서는 중괄호로 묶어서 계산식을 수행할 수도 있다.

void main() {
  var name = '홍길동';
  var age = 10;
  var intro = '안녕 내 이름은 $name 이고, 나이는 ${age + 1} 이야.';
  print(intro);
}
결과 
안녕 내 이름은 홍길동 이고, 나이는 11 이야.

 

Collection For

위에서 설명한 바와 같이 collection 안에서 for 문을 사용해서 배열을 초기화 할 수 있다.

int 타입도 가능하고 String 타입도 가능하다.

void main() {
  var oldNums = [0, 1, 2, 3, 4];
  var newNums = [10, 11, 12, 13, 14, for (var num in oldNums) num];
  print(newNums);
}
결과
[10, 11, 12, 13, 14, 0, 1, 2, 3, 4]

 

Maps

Java 와 동일하게 <key, value> 값을 갖는 자료형이다. 특별하게 다르진 않음.

var 로 지정해도 되고 Map<> 으로 타입을 명확하게 지정해주어도 상관 없으며 key 나 value 의 타입이 다른 collection 타입이어도 상관 없다.

void main() {
  var maps = {0: true, 1: false, 2: true};
  Map<String, String> strMap = {"str1": "str01", "str2": "str02"};
}

 

Sets

Set 은 중복되지 않는다 라는 점에서 list 와 가장 큰 차이점을 가지고 있다. list 는 초기화 할 때 대괄호([]) 를 사용하고 set 은 중괄호({}) 를 사용한다.

void main() {
  var sets = {1, 2, 3, 4, 5};
  sets.add(1);
  sets.add(1);
  sets.add(1);
  print(sets);

  var lists = [1, 2, 3, 4, 5];
  lists.add(1);
  lists.add(1);
  lists.add(1);
  print(lists);
}
결과
{1, 2, 3, 4, 5}
[1, 2, 3, 4, 5, 1, 1, 1]

 


Functions

 

Named Parameters

함수를 호출할 때 파라미터 이름에 직접적으로 값을 대입하는 방법이다.

Named Parameter 를 사용할 때는 순서는 상관이 없다!

Named Parameter 를 사용하기 위해서는 함수 선언부에서 parameter 들을 중괄호로 감싸주어야 한다.

이 후 두가지 방법이 있다.

1) parameter 의 default 값을 설정해주거나,

2) required 로 선언하여 무조건 호출할 때 매개변수를 넘기도록 함수를 선언하는 방법이 있다.

// 1) 방법
String sayHello({String name = '익명', int age = 0}) {
  return "sayHello) 내 이름은 $name 이고 나이는 $age 이야";
}

// 2) 방법
String sayHello2({required String name, required int age}) {
  return "sayHello2) 내 이름은 $name 이고 나이는 $age 이야";
}

void main() {
  print(sayHello());
  print(sayHello2(name: "홍길동", age: 11));
}
결과
sayHello) 내 이름은 익명 이고 나이는 0 이야
sayHello2) 내 이름은 홍길동 이고 나이는 11 이야

 

Optional Positional Parametes

 

QQ Operator

null 인 경우 대체하는 생소한 operator 이다. 해당 연산자를 사용하면 코드가 간결해진다는 장점이 있다.

QQ Operator 는 여러 개가 있지만 '??' 와 '??=' 만 살펴보도록 한다.

먼저 '??' 의 경우에는 좌항이 null 이거나 값을 사용할 수 없는 경우 우항을 반환하는 연산자이다.

String upperCase(String? name) => name?.toLowerCase() ?? "익명";

void main() {
  print(upperCase("길동이"));
  print(upperCase(null));
}

'??=' 는 할당받을 변수가 null 일 경우 우항에 있는 값을 대입할 수 있도록 하는 연산자이다.

다음과 같이 이미 첫번째 홍길동이라고 할당받으면 두번째 홍길동은 값을 대입할 수 없다는 warning 코드를 뱉고 프로그램이 종료된다.

void main() {
  String? name;
  name ??= '첫번째 홍길동';
  name ??= '두번째 홍길동';
  print(name);
}
결과
main.dart:4:3: Warning: Operand of null-aware operation '??=' has type 'String' which excludes null.
  name ??= '두번째 홍길동';
  ^
첫번째 홍길동

 

Typedef

C 언어의 typedef 와 동일해 보인다. 타입을 내가 원하는 이름으로 지정하는 것이다.

타입이 길다면 유용하게 쓰일 듯!

typedef strStrMap = Map<String, String>;

void main() {
  strStrMap maps = {"strKey": "strValue"};
}
결과
길동이
익명

 

'언어 > Dart' 카테고리의 다른 글

JSON 다루기  (0) 2024.12.02
[Dart] 자주 사용되는 Collection 타입 데이터 처리 메서드  (0) 2024.10.29

댓글