Vintage appMaker의 Tech Blog

[Dart] Dart 빠르게 배우기 본문

Source code or Tip/Flutter & Dart

[Dart] Dart 빠르게 배우기

VintageappMaker 2020. 7. 15. 21:32

 

Dart 배우기


Ultra Quick Dart

개발자가 단시간에 Dart를 학습 및 사용해야할 경우가 있다. 그 때를 위해 최소한의 서바이벌 Dart 지식을 정리한 프로젝트이다.
java나 C/C++의 기본문법과 타언어의 문법이 <직관적으로 혼용> 되었다고 생각하면 학습이 빨라진다.

1. main 함수. 출력함수. 종결자. 주석

main 함수는 java, c/c++과 유사함. 출력함수는 print. 종결자는; 주석은 //, /**/, ///

void main() {
  // 주석은 java나 c와 같음.
  print('Hello, World!');
}
2. 변수

기본적으로 Data형이 지정되어야 함. 그러나 var를 선언하고 값을 넣으면 자동으로 데이터형이 지정됨. 한 번 지정된 변수는 데이터형을 변경할 수 없음. dynamic 키워드를 사용하면 변경가능.

  1. var 변수 = 값
  2. 데이터형 변수
  3. dynamic(모든 데이터형 kotlin의 any와 같음)
  var name;
  name = "Hi";
  // 아래는 에러임
  // name = 1
  // name은 "hi"가 입력되어 String임.
  String myName = "psw";
  dynamic any = "any";
  any = 0.98;
3. 기본 데이터 형

숫자형. 문자형. bool형

  1. 숫자형(int, double, num)
  2. 문자형(String)
  3. 부울린형(bool)
  int nNum = -1;
  double nNum2 = 0.23;
  num anyNum = 0.23 * 4;

  String result ="";
  bool bIsOk = false;
4. Null-aware operators

함수형 언어에서 찾아보기 쉬운, null을 비교분석하는 연산자.

  1. ?. [object에서 null이 아니면 실행]
  2. ?? [기본값에서 null일경우 디폴트값 대입]
  3. ??= [object에서 null일경우 디폴트값 대입]
  var nullVal = null;
  var rst = nullVal ?? 3;
  print(rst);
5. 제어문(if, switch)

직관적으로 이해할 수 있는 문법.

  1. if else else if
  2. switch() .. case 문
  var nNumber = 2;
  if( nNumber < 2){
    print ("if ${nNumber}");
  } else if (nNumber == 3){
    print ("else if ${nNumber}");
  } else {
    print ("else ${nNumber}");
  }

  var bTrue = (10/2 > 5) ? true : false; 

  var nSel = 2;
    switch(nSel){
      case 1: break;
      case 2: {
        print ("2");
        break;
      }
  }
6. 반복문(do while, for)

직관적으로 이해할 수 있는 문법.

  1. do{}while(), while()
  2. for(){}
  for (var i = 0; i < 10; i++) {
    print(i);
  }

  var n = 0;
  while( n < 10){
    print (n);
    n++;
  }
7. 함수

java와 유사함.

  1. 함수내 함수를 정의가능
  2. => 를 사용하여 인라인함수 구현가능
  void test(String s) {
      print (s);
    }

  String inlineTest(String s) => s + " (=>)inline function";

  test("inner function");
  print(inlineTest("inline function") );
8. String

java와 kotlin의 기능을 포함하고 있음.

  1. 문자열 안에 $변수명 또는 ${}로 코드실행가능. """ """로 긴문자열 처리가능
  print("${DateTime.now()}");
  print("${inlineTest}");
9. 함수의 파라메터

형태는 자바와 유사함.

  1. 이름있는 파라메터 함수명 이후 ()안에 {}로 정의함.
  2. 옵션적인 파라메터는 ()안에 []로 정의함
  void namedFunc ({String name, int age}) => print ("${name} ${age}");
  namedFunc(name: "snake", age: 51);

  void optionFunc (String name, [int age = 51]) => print ("${name} ${age}");
  optionFunc("snake");
10. List, set

java, Kotlin의 List와 유사함

  1. List(), [] 로 객체생성
  2. <> 제너릭으로 선언안하면 다양한 값을 넣을 수 있음.
  3. ...로 각 item을 추가할 수 있음(list 객체의 addAll과 유사).
  4. set은 List와 유사하나 item이 중복안됨.
  5. Set(), {}로 객체생성.
    {
      // List
      var lst = List();
      lst.add("1");
      lst.add(1);
      print (lst);

      var lst2 = [12, "A", 34.2];
      lst2.add ("huk");
      lst2.add(lst);
      print(lst2);

      var lst3 = [1, 2,...lst2];
      print(lst3);
    }

    //  Set
    {
      var set = Set();
      set.add("aaa");
      set.add("aaa");
      set.add("aaa");
      print(set);

      var set2 = {1, 1, 1, 1, 1, 2, 2, 3, 3};
      set2.remove(3);
      print(set2);
    }
11. Map

java의 map과 유사한 key, value 형태이지만,
일반적으로 형을 지정하지 않고 사용함.

  1. Map(), {}
  {
    var mp = Map();
    mp["A"] = 1;
    mp[1] = 1;
    print(mp);

    var mp2 = {
      1 : "one",
      2 : "two",
      "three" : 3
    };
    mp2.remove(2);
    print(mp2);
  }
11. lambda와 closure

lambda는 익명함수이다. (파라메터) {구현} 형식이다.
함수를 리턴하거나 넘길 때, 데이터형은 Function이다.
값으로 넘길 때는 (파라메터){구현}

  {
    var fnLambda = (name) => {print(name)};
    fnLambda("lambda");

    Function fnClosure( Function fn,  int baseValue){
      var nNum = baseValue;
      return (addNum) {
        nNum += addNum;
        fn( "$addNum ->  $nNum " );
      };
    }

    var fnClo1 = fnClosure(print, 5);
    fnClo1(2);
    fnClo1(3);
    fnClo1(4);
  }
12. casting, type check

형변환과 타입체크 방법

  1. 문자열 -> 숫자(int, double, num의 parse() )
  2. 숫자 -> 문자 (toString())
  3. 객체의 casting은 as를 사용함
  4. type check는 is를 사용함.
  {
    var sNum = "1";
    var sum  = int.parse(sNum) + num.parse(sNum) + double.parse("34.3") ;
    print( sum );

    var n  = 0;
    print( n.toString() + " 입니다" );

    if (n is num){
      print ("숫자");
    } else {
      print ("숫자아님");
    }
  }
13. class

문법은 기본적으로 java와 유사하다.

  1. new를 사용할 수도 안할 수도
  2. 이름있는 생성자를 [클래스명.메소드명]으로 사용가능
  3. 프로퍼티와 메소드는 자바와 동일
  4. static 메소드는 자바와 동일
  5. getter/setter 메소드 지원
  6. private/public 키워드없음. 이름에 _(언더스코어)를 쓰면 private으로 한다고 하지만, 외부사용은 가능함.
  7. 상속은 extends
class Test{
  String name;
  int _age = 0;
  int get age => _age;
      set age(int n) {
        if (n > 40) _age = 40;
        else _age = n;
      }

  Test(){
    instanceCount++;
  }

  Test.namedInit(String name){
    this.name = name;
    instanceCount++;
  }

  static int instanceCount = 0;
}

...

{
    var t = Test();
    var t2 = new Test();
    var t3 = Test.namedInit("name");
    print (t2.name);
    print (Test.instanceCount);
    t2.age = 51;
    print (t2.age);
}
14. Abstract와 Factory

java와 같음.

  1. abstract로 선언, implements로 구현, @override로 정의.
  2. factory로 abstract 클래스에서 구현된 객체 넘길 수 있음.

abstract class Animal{
  factory Animal(int type){
    if(type == 0) return Dog();
    if(type == 1) return Cat();

    return null;
  }

  void cry();
}

class Dog implements Animal{
  @override
  void cry(){ print ("미야오옹~");}
}

class Cat implements Animal{
  @override
  void cry(){print ("왈왈~");}
}

...

{
  var animals = [Animal(0), Animal(1)];
  animals.forEach( (ani){
    ani.cry();
  } );
}
15. mixin

다중상속이라고 보면 됨. java의 철학과는 안맞음.

  1. mixin 정의된 클래스가 누군가를 상속받고자 한다면 on
  2. mixin 정의된 클래스를 상속받고자 한다면 with
class Account{
  int money = 0;
}

mixin Salary on Account{
  void saveMoney(int n) => money += n;
}

class Worker extends Account with Salary{
  void showMeTheMoney() => print (money);
}

...

{
  var obj = Worker();
  // 1부터 10까지 
  [ for(var i=0; i<10; i+=1) i ].forEach( (n){
    obj.saveMoney(n);
  } );
  obj.showMeTheMoney();
}
16. 확장함수

코틀린의 확장함수와 동일. 이미 정의된 클래스에 메소드를 추가.

  1. extension on 클래스명 {} 안에 메소드를 정의.
extension on String {
  String multiString(int n){
    return this * n;
  }
}

...

print ( "AAA ".multiString(3) );
17. 비동기
  1. 함수는 Future로 선언
  2. 비동기 함수를 사용한다면 async{}로 코드를 감싼다.
  3. 비동기 함수를 결과를 기다려야 한다면 await 함수()
  4. Future 함수의 delay()로 지연가능
  {
    Future<String> waitAndGo() {
      return Future.delayed(Duration(seconds: 5), () => 'delayed 5 second.');
    }

    void asyncProcess () async {
      print('waitAndGo...');
      var order = await waitAndGo();
      print('wait Result: $order');
    }

    asyncTest() async {
      await asyncProcess();
    }

    asyncTest();

  }
18. 예외처리

예제를 참고

  {
    try {
      var rst = 1000 ~/ 0;
      print(rst);
    } on IntegerDivisionByZeroException{
      print ( "divided error" );
    } catch(e){
      print (e.toString() );
    }
  }

19. typedef

함수형 변수의 크기를 정의

  1. C의 typedef와는 다름
  {
    void F1 (String s) => print (s);
    void F2 (String s) => print (s);
    void F3 (String s, int n) => print (s * n);

    [F1, F2, F3].forEach((f){
      if (f is fnType){
        f("${f} is fnType");
      } else {
        f("${f} not fnType\n", 1);
      }
    });

  }


// 함수데이터형 정의(C의 typedef와는 다름)
typedef fnType = void Function(String);
Comments