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 |
댓글