[Flutter] 1. Dart 문법

편준민's avatar
May 21, 2025
[Flutter] 1. Dart 문법

1️⃣ Dart 언어를 사용해보기

2️⃣ 문법

1. 변수

void main() { int n1 = 1; double d1 = 10.1; bool b1 = true; String s1 = "홍길동"; print("n1:${n1}"); print("d1:${d1}"); print("b1:${b1}"); print("s1:${s1}"); //타입 확인 print(d1.runtimeType); }
notion image

2. 타입 추론

💡
처음 설정한 타입을 바꿀 수 없음. n1 = “문자열”은 String 타입이기 때문에 오류가 남
void main() { var n1 = 1; //n1 = "문자열"; n1 = 3; print(n1); print(n1.runtimeType); }
notion image

3. Dynamic 타입

💡
타 언어에서는 Object 타입으로, 모든 타입을 받을 수 있다. 타입 변경이 계속 가능하다.
dynamic n2 = 1; // dynamic 타입으로 타입 변경이 가능하다 print(n2.runtimeType); n2 = "문자열"; print(n2.runtimeType);
notion image

3️⃣ 연산자

💡
연산자는 총 3가지가 있다.
  • 산술 연산자 : 수학에서 사용하는 사칙 연관과 나머지 연산을 포함하는 연산자
  • 비교 연산자 : 두 개의 값을 비교하여 결과를 참/거짓으로 반환하는 연산자
  • 논리 연산자 : 두 개의 참/거짓 값으로 새로운 참/거짓을 반환하는 연산자

1. 산술 연산자

void main() { // 더하기 print("3+2=${3 + 2}"); // 빼기 print("3-2=${3 - 2}"); // 곱하기 print("3*2=${3 * 2}"); // 나누기 print("3/2=${3 / 2}"); // 나머지 print("3%2=${3 % 2}"); // 몫 구하기 print("3~/2=${3 ~/ 2}"); }
notion image

2. 비교 연산자

void main() { // 같다 print("2=3 → ${2 == 3}"); // 다르다 print("2!=3 → ${2 != 3}"); // 왼쪽 값 보다 크다 print("2<3 → ${2 < 3}"); // 왼쪽 값 보다 작다 print("2>3 → ${2 > 3}"); // 왼쪽 값 보다 크거나 같다 print("2<=3 → ${2 <= 3}"); // 왼쪽 값 보다 작거나 같다 print("2>=3 →> ${2 >= 3}"); }
notion image

3. 논리 연산자

void main() { // 부정 print("! true → ${!true}"); // AND print("true && false → ${true && false}"); print("true && true → ${true && true}"); // OR print("true || false → ${true || false}"); }
notion image

4️⃣ 조건문

💡
JAVA와 동일함
void main() { int point = 90; if (point >= 90) { print("A학점"); } else if (point >= 80) { print("B학점"); } else { print("F학점"); } }
notion image

5️⃣ 삼항연산자

💡
Dart에 삼항연산자는 값이 표현식으로 표현됨
표현식은 값을 출력, 리턴, 결과값을 응답해주는 것이다.
void main() { int point = 60; // 표현식(값을 출력, 리턴, 결과값을 응답해주는 것) String result = point >= 60 ? "합격":"불합격"; print(result); }
notion image

6️⃣ 함수

💡

함수란

  • *함수(Function)**는 어떤 작업을 수행하는 코드의 묶음입니다.
한 번 정의해두면, 필요할 때마다 이름을 불러서 실행할 수 있습니다.

함수의 목적

  • 코드 재사용 : 중복된 코드를 줄일 수 있음
  • 가독성 향상 : 코드가 더 이해하기 쉬워짐
  • 유지보수 용이 : 한 곳만 수정하면 전체에 반영 가능

익명함수와 람다식

익명함수와 람다식의 큰 차이는 람다식에서는 return 키워드를 적지 않아도 값이 반환되지만, 익명함수는 값을 반환하려면 return 키워드를 꼭 적어야 합니다.
void f1() { print("f1 호출됨"); } void f2(int n1, int n2) { print("f2 호출됨 : ${n1 * n2}"); } int f3(int n1, int n2) { return n1 * n2; } void main() { f1(); f2(5, 3); int result = f3(8, 4); print("f3 result : ${result}"); } // 함수 : 람다 (이름이 없는 함수 축약) // 익명함수 var f1 = () { print("f1 호출됨"); }; // 람다 문장 var f2 = () => print("f2호출됨"); // 람다 표현식 var f3 = () => 1; // 함수 int f4() { return 1; } void f5() { print("f5호출됨"); } void main() { f1(); } // 버튼 class Button { // 디자인 void onClick(Function be) { be(); } } class CheckBox { // 디자인 void onSelected(Function be) { be(); } } void main() { Button b = Button(); b.onClick(() { print("선 그리기"); }); CheckBox ch = CheckBox(); ch.onSelected(() { print("점 그리기"); }); }

7️⃣ null 처리

💡
null 처리 방법 3가지

  • ? (null 인식 연산자) : 앞에 있는 값이 null 이면 전체 식의 결과가 null, null이 아니면 함수를 실행
  • ?? (null 대체 연산자) : 앞에 있는 값이 null이면, ?? 뒤에 있는 값을 대신 사용.
  • ! (null 부정 연산자) : 이 값은 절대 null이 아니라고 Dart에게 확신시켜주는 연산자. 만약 실제로 null이면 오류 발생
// null처리 // ? (null 인식 연산자) // ?? (null 대체 연산자) // ! (null 부정 연산자) // ?타입 = String? String? username = null // null 인식 연산자 예제 void main() { int len = username?.length ?? 0; print(len); } // null 대체 연산자 예제 void main() { String value = username ?? "ssar"; int len = value.length; print(len); } // null 부정 연산자 예제 void main() { int len = username!.length; print(len); }

8️⃣ 선택적 매개변수

💡
Dart는 함수의 매개변수를 필수가 아닌 선택적으로 만들 수 있다. 함수를 만들 때 꼭 안 넣어도 되는 값 을 매개변수로 만들 수 있다.
즉, 넣어도 되고 안 넣어도 되는 "선택사항"인 값이다.

{타입? 변수} : 선택적 + null이 가능하다.
{타입 변수 = 기본값} : 선택적 + 기본값이 있다.
{required 타입 변수} : 선택이 아닌 필수! 꼭 넣어야 함
// 선택적 매개변수 // 1. 키값으로 전달할 수 있다. void add({int? n1, int? n2}) { print(n1! + n2!); } void add2({int n1 = 0, int n2 = 0}) { print(n1 + n2); } void add3({required int n1, required int n2}) { print(n1 + n2); } void add4(int n1, {required int n2, int n3 = 0}) { print(n1 + n2 + n3); } void main() { //add(n1: 1, n2: 3); //add2(n1: 1); //add3(n1: 1, n2: 3); add4(1, n2: 3); }

9️⃣ Class

💡
사람이 직접 만든 데이터 설계도이다.
예를 들어, 자동차(Car)를 만들려면 색깔, 속도, 브랜드 같은 정보가 필요하다.
그리고 달린다(run) 같은 동작도 필요하다.
이런 "정보(변수)"와 "동작(함수)"를 묶어서 정의해두는 게 클래스입니다.

Class와 Object
  • class: 자동차의 설계도 (틀)
  • object: 설계도로 만든 실제 자동차 (실제 값)
// 클래스 class User { String username; String password; User(this.username, this.password); } void main() { User u1 = User("ssar", "1234"); print(u1.username); print(u1.password); } // // 클래스 class User { String username; String password; User({required this.username, this.password = "1234"}); } void main() { User u1 = User(username: "ssar"); print(u1.username); print(u1.password); } //3 // 클래스 class User { String username; String password; User(String username, String password) : this.username = username, this.password = password == "1234" ? "5678" : password; } void main() { User u1 = User("ssar", "1234"); print(u1.username); print(u1.password); } //4 // 클래스 class User { String username; String password; User(this.username, this.password); void init() { if (username == "ssar") { if (password == "1234") { this.password = "9999"; } } } } void hello(User u) {} void main() { hello(User("ssar", "1234")..init()); }

🔟 추상클래스

💡
추상 클래스는 "공통 기능을 정의해두지만, 아직 완성되지 않은 클래스"입니다.
  • abstract 키워드를 붙여서 만듭니다.
  • 안에 있는 함수 중 내용이 없는 함수(추상 메서드)가 있으면, 반드시 추상 클래스가 되어야 해요.
  • 이 클래스는 직접 사용 못 해요. 상속해서 사용해야 해요.
// 상속 class Button { String text; String color; int x; int y; int width; int height; Button( this.text, { this.color = "회색", this.x = 0, this.y = 0, this.width = 200, this.height = 150, }); Button.block( this.text, { this.color = "회색", this.x = 0, this.y = 0, this.width = 100000000, this.height = 150, }); static Button inlineButton(String text) { return Button(text); } } void main() { Button basicButton = Button("로그인"); Button redButton = Button("로그인", color: "red"); Button blockButton = Button.block("회원가입"); Button inlineButton = Button.inlineButton("회원가입"); } // abstract class Button { void good(); void hello() { print("hello"); } } class TextButton extends Button{ @override void good() { // TODO: implement good } } // // 상속 class Burger { String name; Burger(this.name); } // is class ChickenBurger extends Burger { int price; ChickenBurger(this.price, super.name); } class CheeseBurger extends Burger { CheeseBurger(String name) : super(name); } void main() { Burger b1 = CheeseBurger("치즈버거"); Burger b2 = ChickenBurger(1000, "치킨버거거"); } // 상속 class Button { String text; String color; int x; int y; int width; int height; Button( this.text, { this.color = "회색", this.x = 0, this.y = 0, this.width = 200, this.height = 150, }); Button.block( this.text, { this.color = "회색", this.x = 0, this.y = 0, this.width = 100000000, this.height = 150, }); static Button inlineButton(String text) { return Button(text); } } void main() { Button basicButton = Button("로그인"); Button redButton = Button("로그인", color: "red"); Button blockButton = Button.block("회원가입"); Button inlineButton = Button.inlineButton("회원가입"); } // //mixin class Engine { int power = 5000; } mixin class Wheel { int size = 21; } // has class Car with Engine, Wheel {} void main() { Engine e = Engine(); Car c1 = Car(); print(c1.power); print(c1.size); }
Share article

YunSeolAn