
구글이 멀티 플랫폼 상에서 동작되도록 하는 앱을 위해 디자인된 프로그래밍 언어이다. 기본적으로 C언어의 문법과 거의 같으며 Java, C#, Javascript와 같은 기능적 스트럭처를 추가한 언어로, 언급된 언어보다 간결하고 강력한 기능을 지원한다. 모바일, 데스크톱, 서버, 웹 앱 용도에 사용된다.
Dart는 구글에서 2017년 발표한 크로스플랫폼 앱 프레임워크인 Flutter가 사용하고 있다. 이는, Flutter를 배우려면 Dart를 꼭 배워야한다는 뜻이다.
자, 이제 Dart의 기본 문법에 대해 알아보자.
- Dart를 활용하여 프로그래밍 할 때 가장 기본이 되는 단위
- 특정한 값(데이터)를 담아두는 그릇
- 데이터의 유형.
기본형
자료형
확장형
가변형
- var : 최초 한번 부여된 타입이 고정적으로 사용.
- dynamic : 타입이 코드 진행 중에라도 언제든 변환.
타입 변수이름 = 값; // --> 함수 끝에는 항상 ;(세미콜론)을 입력
// (슬래시 2개)
어느정도 프로그래밍 언어에 익숙하다면 VSCode를 사용하여도 문제 없지만 만약 익숙하지 않거나 환경 구축이 안돼있다면, 실습 가능한 웹 IDE 환경인 DartPad 사이트를 이용하면 된다.
사용법은 생략하고, 실습을 시작해보자.
void main() {
// 참 / 거짓형 bool
bool isTrue = true;
// 정수형 int
int num = 100;
// 실수형 double
double num2 = 3.14;
double num3 = 3; // 실수형인 double은 정수도 포함하기 때문에 정수도 선언 가능
// 문자열형 String
String string = 'Hello World'; // 문자열을 작은 따옴표로 감싸주기
// Null형 null
Null thisIsNull = null;
print(isTrue);
print(num);
print(num2);
print(num3);
print(string);
print(thisIsNull);
}

print시 변수들이 모두 정상적으로 출력되는 모습.
void main() {
// 가변형 var / dynamic
var value = 1;
value = 'is Error?'; // 에러 발생
value = 2; // 정상 --> var는 가변형이어도 타입이 달라지면 에러가 발생
dynamic dynamicValue = 100;
dynamicValue = 'Hello'; // 정상 --> dynamic은 타입이 달라져도 에러가 발생하지 않음
print(dynamicValue);
}

에러가 발생하는 value = 'is Error?'; 구문을 지우고 실행한 모습. 이 구문을 넣으면 에러가 발생하여 실행이 되지 않는다.
이와 같이 같은 가변형이지만, var과 dynamic은 차이점이 있다는 것을 알았다.
- 변수는 한 번 할당한 값을 여러 번 수정할 수 있는 것이 특징
- 그렇다면 값을 한 번 할당하면 바꿀 수 없는 것은?
- -> 상수
- Dart에는 상수를 선언하는 방법이 두 가지가 존재
const // --> compile 시점에 상수 처리될 경우에 활용
final // --> 프로그램의 진행 중에 상수 처리될 경우에 활용
- 프로그래밍 언어에서 사용되는 기호 혹은 단어로,
하나 이상의 변수나 값을 가지고 수행할 연산을 나타내는 단위.
산술 연산자
비교 연산자
논리 연산자
할당 연산자
이외에도 삼항 연산자, 비트 연산자(Dart에서는 잘 사용되진 않음) 등 여러 연산자가 존재
- Dart는 2.12 버전부터 Null값에 대한 안정성을 위해 Null Safety 라는 개념이 도입됨.
- 관련하여 추가된 타입과 연산자가 존재
void main() {
// 연산자
// 산술 연산자
// 사칙연산( +, -, *, / )
int num1 = 10;
int num2 = 20;
print(num1 + num2);
print(num1 - num2);
print(num1 * num2);
print(num1 / num2); // 다른 값들은 number형태(정수형 int와 실수형 double을 모두 아우르는 형태)를 이루지만,
// 나눗셈은 항상 double 형태로 고정이 됨.
int num3;
// num3 = num1 / num2; // --> 에러가 발생. 나눗셈은 int 타입으로 나오지 않기 때문에, 타입을 double로 부여해줘야 함.
// print(num3);
String str1 = 'Hello';
String str2 = str1 + ' World'; // --> 문자열 연산자 String에 + 를 사용 가능. 이 외에 다른 연산자는 불가능.
String str3 = '$str2 World'; // --> $(달러)를 쓰고 String 변수를 입력하면, 그 스트링 변수의 실제 문자열을 그대로 가져와서 사용할 수 있음. 이런 경우에 $를 많이 씀.
// * 파이썬의 f-String 에서 {변수이름}을 넣어서 사용하는 것과 비슷한 느낌이라고 생각되는 듯..?
print(str3);
}

void main() {
// 연산자
// 비교 연산자
int num4 = 20;
int num5 = 30;
print(num4 == num5); // 20과 30의 값이 같지 않기에 false가 출력됨.
print(num4 != num5); // 20과 30의 값이 같지 않기에 true가 출력됨.
print(num4 < num5); // 20보다 30이 크기 때문에 true가 출력됨.
// 이 외에 <, >, <=, >= 등
// 논리 연산자 ( &&(and), ||(or) )
bool bool1 = true;
bool bool2 = false;
print(bool1 && bool2); // and 연산자기에 true와 false 를 비교했을 때 false 값이 출력됨.
print(bool1 || bool2); // or 연산자기에 true와 false 를 비교했을 때 true가 하나 있기에 true 값이 출력됨.
print(!bool1); // ! 는 뒤에 바로 오는 boolean의 값을 반대로 바꿔줌. 따라서 결과도 반대로 출력됨.
// 삼항 연산자 ( 논리연산 ? 참일 경우 : 거짓일 경우 )
String answer = 10 < 20 ? '참입니다.' : '거짓입니다.'; // Flutter에서 삼항 연산자는 자주 쓰임.
print(answer);
}

void main() {
// 연산자
// 할당 연산자 ( =, +=, -= )
int num6 = 10;
num6 += 20; // --> 이 코드와
num6 = num6 + 20; // --> 이 코드는 같음. *=, -=.. 등도 마찬가지..
print(num6);
// Null 처리 연산자
int? num7;
int num8 = 10;
print(num7); // 62번 줄에서 int 뒤에 Nullable Type인 ?을 붙히지 않으면 컴파일 에러가 발생할 것.
print((num7 ?? 5) + num8); // --> null 값에 ?? 연산자를 사용하면 임시로 값을 부여할 수 있다.
}

- 클래스는 일종의 객체를 만들기 위한 Template
- 지금 당장 객체, 템플릿이란 말이 어렵게 들릴 것이다. Dart는 객체지향 언어 중 하나인데, 흔히들 보통 객체를 완벽하게 이해하는 것이 프로그래밍 입문에서 제일 어려운 레벨중 하나라고 하는데, 객체라는 것은 단순하게 이야기하면 현실에 존재하는 물체 하나(예를 들어 핸드폰)라고 이해하면 좋다. 만약에 이해가 안되더라도 기억하고 넘어간다면, 어느 순간 이해가 되는 시점이 올 것이다.
- 클래스를 활용하여 일종의 데이터와 코드를 그룹화해서 관련된 코드를 같이 유지하고, 객체를 쉽게 만들어 객체지향 프로그래밍을 효과적으로 활용할 수 있다.
- 클래스의 인스턴스를 생성하는 데 사용되는 코드이다.
- 생성자를 통해 매개변수를 전달하거나, 클래스 내 필드의 초기값을 설정하는 등의 작업을 할 수 있다.
Default constructors : 기본 생성자로, 생성자를 선언하지 않을 경우 제공되는 생성자.
Named constructors : 개발자가 필요에 의해 생성한 생성자로, 클래스에 대한 여러 생성자를 구현하거나, 추가적인 클래스의 명확성을 제공.
Redirecting constructors : 목적이 동일한 생성자로 전달하기 위한 생성자로, 생성자의 본문은 비어 있지만, 전달 된 생성자에 대한 초기값 등을 구현할 때 활용.
Const constructors : 상수 생성자로, 클래스가 불변의 객체를 생성하는 경우 활용.
Factory constructors : 매번 새로운 인스턴스를 만들지 않는 생성자를 활용할 때 사용한다. 이미 존재하는 인스턴스를 반환하거나, 단순한 초기값을 부여가 아닌 연산이 필요한 객체 생성 시 활용한다.
// 안정우
// 클래스
// 클래스 기초
// 기본 생성자(Default constructors)
void main() {
Point point = Point(1, 2); // this.x, this.y 두 개를 받는다고 선언했기에, 해당하는 값이 들어가야 함. 1,2를 넣어준 모습.
print(point); // Instance of 'Point' 가 출력되면서 point라는 객체가 정상적으로 생성되었음을 확인할 수 있음.
print(point.x); // 포인트 안에 어떤 값이 선언됐는지 확인할 때는, point 뒤에 .을 붙혀야 함.
print(point.y); // x와 y가 각각 1, 2로 출력되는 것이 확인됨.
Point aPoint = Point(2, 5); // aPoint라는 새로운 객체에 this.x, this.y에 2, 5를 넣어준 모습.
print(aPoint.x);
print(aPoint.y);
// 정상적으로 2, 5가 출력됨.
Point bPoint = Point(10, 4); // bPoint라는 새로운 객체에 this.x, this.y에 10, 4를 넣어준 모습.
print(bPoint.x);
print(bPoint.y);
// 정상적으로 10, 4가 출력됨.
}
// * 클래스를 만들 때에는 기본적으로 기존의 메인 함수 밖에서 만드는 것.
// 명명 생성자(Named constructors)
class Point { // --> 클래스의 첫 음절은 대문자로 해야함. Dart 프로그래밍의 암묵적인 룰.
double x;
double y;
Point(this.x, this.y); // --> 명명 생성자는 개발자가 임의적으로 생성자를 아래에다 만들어줘야 함.
}

Dart 개발환경 구축, Dart의 함수에 대해 작성 예정