본문 바로가기

🥸 웹앱개발 이모저모/Flutter

Dart 기초 문법

Dart 기초 문법

한줄 후기 C언어 문법과 굉장히 비슷한 것 같다!

변수 선언

void main() {
    var name = '변수';
}

// name이라는 변수에 '변수'라는 글자를 저장
  • 변수 값을 바꾸려면?
  • void main() { var name = '변수'; name = '새로운 값'; }
  • 같은 이름의 변수를 두 번 정의할 수는 없다.
      void main() {
          var name = '변수1';
    
          var name = '변수2';
      }
  • (다른 언어를 배웠다면 쉽게 이해할 수 있는 부분!)

정수 선언

void main() {
    int num1 = 2;
    int num2 = 3;

    print(num1 + num2); // 5 출력
    print(num1 - num2); // -1 출력
    // 곱셈 *, 나누셈 /, 나머지 %
}
  • 실수는 double

bool

void main() {
    bool isTrue = true; //'true'와는 전혀 다름!!!
    bool isFalse = false;
}
  • 불리안은 두가지 값 밖에 없다.

String 타입

글자 타입

void main() {
    String name1 = '무지개';
    String name2 = '말랑콩떡';
}
  • 그렇다면 var과 String의 차이점은 무엇인가?
    • var은 오른쪽의 변수 값을 통해 타입을 유추함
  • 그러면 var만 쓰면 안돼?
    • 지금은 몇줄 안되는 코드이지만 나중에 몇백줄의 코드를 작성하게 된다면 보기가 어려움. 이 변수가 어떤 타입인지 명시해 주는 것이 알아보기에 효율적이다.
    • → 직접 명시해주는 것을 습관으로 들이자.
  • String 덧셈
void main() {
    String name1 = '무지개';
    String name2 = '말랑콩떡';

    print(name1 + name2); //무지개말랑콩떡
    print(name1 + ' ' + name2); //무지개 말랑콩떡
}
  • 문자열에 변수 넣기
void main() {
    String name1 = '무지개';
    String name2 = '말랑콩떡';

    print('${name1} ${name2}'); //무지개 말랑콩떡
    print('$name1 $name2'); //무지개 말랑콩떡 / {} 생략 가능
}

dynamic 타입

void main() {
    dynamic name = '무지개';
    var name2 = '말랑콩떡';

    print(name.runtimeType); //String
    print(name2.runtimeType); //String

    name = 1; //dynamic은 타입을 계속 변경할 수 있음
    //name2 = 2; //error 발생 (var은 첫 선언한 값의 타입으로 픽스됨)
}

null

  • nullable : null이 될 수 있다. - ?
  • non-nullable : null이 될 수 없다. - !
  • null : 아무런 값이 없다.
void main() {
    //String name = null; // error String은 null이 될 수 없음
    String? name = null; //?를 넣어줌으로써 null이 될 수 있음

    String name2 = '무말콩';
    print(name2!); //!를 넣음으로써 이 값은 null이 아니다

final, const

  • final, const로 선언하게 되면 변수 값을 변경할 수 없음
  • 데이터 타입을 생략해서 선언해도 OK
  • final과 const의 차이
    • final : 빌드타임을 몰라도 됨
    • const : 빌드타임을 알아야 함
    • 빌드 타임 : 지금 작성하는 코드의 값을 알 수 있어야함. (코드의 값 = 기계어로 해석이 되야함)DateTime은 프로그램을 실행했을 때 해당 코드의 줄이 실행되는 시간임. 그렇기 때문에 실행하기 전에는 DateTime을 알 수가 없다. (그러므로 const는 빌드 타임을 알아야하는데 DateTime의 빌드타임은 알 수 없기때문에 오류 발생)
    • void main() { final DateTime now = DateTime.now(); print(now); const DateTime now2 = DateTime.now(); //error : 빌드타임을 모르기 때문 }

operate

  • ??=
  • void main() { double? num = 4.0; print(num); //4 num = 2.0; print(num); //2 num = null; print(num); //null num ??= 3.0; //num이 null이면 3.0으로 바꿔라, null이 아니면 원래값 그대로 print(num); //3 }
  • 값 비교
  • void main() { int num1 = 2; int num2 = 3; print(num1 > num2); // false print(num1 == num2); // false print(num1 != num2); // true }
  • 타입 비교
  • void main() { int num1 = 1; print(num1 is int); //true print(num1 is String); //false print(num1 is! int); //false }
  • 논리 연산자(&&, ||)
  • bool result = 12 > 10 && 1 > 0; // and 조건 , 둘 다 만족해야 true print(result); // true bool result1 = 12 > 10 || 1 < 0; // or 조건, 둘 중 하나만 만족해도 true print(result1); // true

List 타입

void main() {
    List<타입> 리스트명 = [값, 값, 값];

    print(리스트명[index]); //해당 index의 값을 출력
}

리스트에는 같은 타입의 변수값만 넣어 주어야한다.

  • 추가
  • void main() { List<int> list = [1, 2, 3]; print(list.length); //리스트 길이 출력 ex) 3 list.add(4); //리스트 값 추가 ex) 1, 2, 3, 4 list.remove(4); //리스트 값 지우기 list.indexOf(3); //해당 값의 인덱스 번호 가져옴 ex) 2 }

Map 타입

void main() {
    Map<키 타입, 값 타입> map명 = {
        '키' : '값'
    };
}
  • 추가Set 타입
    List는 중복돼도 처리X
  • void main() { final Set<String> names = { 'hj', 'Flutter', 'Dart' }; names.add('jenny'); //값 추가 names.remove('jenny'); //값 삭제 print(names.contains('Dart')); //값이 포함되어 있는지 아닌지 출력 ex) true }
  • : 알아서 중복된 값 처리해줌
  • void main() { Map<String, int> map{ 'A' : 1, 'B' : 2 } map.addAll({ 'C' : 3, }); //map 값 추가 map[1]; //해당 인덱스의 키, 값을 가져옴 map['C']; //해당 키에 해당하는 값을 가져옴 map['D'] = 4; // 값 추가 map.remove('D'); // 해당 키와 값을 모두 지움 print(map.keys); //map에서 key값들을 모두 가져옴 print(map.values); //value들을 모두 가져옴 }

Switch

void main() {
    int num = 3;

    switch(num % 3){
        case 0:
            print('나머지가 0입니다');
            break;

        case 1:
            print('나머지가 1입니다');
            break;

        default:
            print('나머지가 2입니다');
            break;
    }
}

Loop

: 반복

  • for문
      void main() {
          int total = 0;
    
          List<int> nums = [1, 2, 3, 4, 5];
    
          //방법 1
          for(int i = 0; i < nums.length; i++){
              total += nums[i];
          }
    
          //방법 2
          for(int number in nums){ //nums의 각 값이 number가 됨
              total += number;
          }
      }    
  • void main() { for(초기값; 범위; 조건){ 실행 코드; } }
    • 조건 확인 후 만족하면 실행
    • void main() { while(조건){ //조건을 만족하는 동안 실행됨.(조건을 만족하지 못하는 즉시 종료) 실행할 코드; } }
    • do-while
      • 일단 한번 실행 후 조건 검사
      • void main() { do { 실행 코드; } while(조건); } 

enum

enum Status { 
    approved,
    pending,
    rejected,
}

void main() {
    Status status = Status.pending;

    if(status == Status.approved){
        print('승인입니다.');
    } else if(status == Status.pending){
        print('대기입니다.');
    } else {
        print('거절입니다.');
    }
}
  • Status status = Status.pending; 말고 String status = ‘pending’; 하고 if(status == ‘approved’)하면 안돼?
    • 가능, 그러나 오타가 났을 때 알아보기 쉽지 않음. Status.approve 이렇게 오타가 나면 에러가 발생하기 때문에 enum을 사용하면 좀 더 편리하다!

 

함수 선언

positional parameter

  • 기본 파라미터, 순서대로 파라미터가 지정된다. (순서가 중요)
void main() { 
    함수명(parameter); //함수 실
}

//함수에 대한 설명
returnType 함수명(parameter) { ... } //함수 정의
// return값이 없다면 void 또는 생략 가능

optional prameter

: 있어도 되고 없어도 되는 파라미터

  • 해당 파라미터에 [ ] 를 해주면 된다.
void main() {
    sumNumber(10); //y,z를 넣지 않아도 오류 X
}

sumNumber(int x, [int y, int z]){
    int sum = x + y + z;

    print(sum);
}
  • 파라미터를 넣지 않으려면 sumNumber(int x, [int y, iny z])sumNumber(int x, [int? y, iny? z]) 물음표를 넣어줘야함.
  • 그러나 y,z가 null이면 int sum = x + y + z; 여기서 오류가 남 (null은 더할 수 없음)
    • 그렇기 때문에 sumNumber(int x, [int y, iny z]) 여기서 기본값을 정의해 주어야함
    • sumNumber(int x, [int y = 10, iny z = 20])

named parameter

: 순서가 중요하지 않은 파라미터, 이름으로 지정함

void main() {
    sumNumber(y : 20, x : 10, z: 30); //파라미터에 이름을 지정해 주어야 함
    // 파라미터의 순서가 달라도 됨. 이름에 따라 지정
}

sumNumber({
    required int x, // 10
    required int y, // 20
    required int z, // 30
    }){
    int sum = x + y + z;

    print(sum);
}
  • optional 방식으로 하고 싶어!
  • void main() { sumNumber(y : 20, x : 10); // z:값 넣게되면 새로운 값으로 지정됨. } sumNumber({ required int x, required int y, int z = 30, // required 없애고 기본값 지정해주기 }){ int sum = x + y + z; print(sum); }
  • positional 방식을 사용하고 싶어
void main() {
    sumNumber(10, z: 40, y: 20); // x값은 positional 방식으로 순서대로 기
}

sumNumber(int x, //중괄호에서 빼주면 됨
    {
    required int y,
    int z = 30,
    }){
    int sum = x + y + z;

    print(sum);
}

화살표 함수

void main() {
    sumNumber(10); //y,z를 넣지 않아도 오류 X
}

int sumNumber(int x, int y, int z) => x + y + z; //x+y+z 값을 반환하는 함수

typedef

: signature에 부합하는 함수들을 모두 사용할 수 있

void main() {
    Operation aperation = add;

    int result = operation(10,20,30); //add 함수가 실행된 결과값

    operation = subtract;

    int result2 = operation(10,20,30); //subtract 함수가 실행된 결과값

    //활용
    int result3 = caclulate(30, 40, 50, add); //add 함수 실
}

//signature
typedef Operation = int Function(int x, int y, int z);

//더하기
int add(int x, int y, int z) => x + y + z; //파라미터 형식 Function이랑 똑같게

//빼기
int subtract(int x, int y, int z) => x - y - z; //파라미터 형식 Function이랑 똑같게

// 활용방식
int calculate(int x, int y, int z, Operation operation){
    return operation(x, y, z);
}
  • 활용 설명
    • caclulate(30, 40, 50, add) 여기서 x에 30, y에 40, z에 50, operation 값으론 add를 받아옴
    • operation(x, y, z)add(30, 40, 50)이 실행됨