[FLUTTER] DART 언어 기초과정 - 1 / A Tour of the Dart Language

in #dart6 years ago (edited)

플러터란 ? 구글에서 개발한 크로스 플랫폼 앱 개발 프레임워크이다. 언어는 구글이 개발한 Dart 를 사용한다. 안드로이드, iOS, Web, Desktop 을 지원하며 구글의 차기 OS Fuchsia의 메인개발환경이 된다고 한다.

출처 : [https://www.dartlang.org/guides/language/language-tour]

  • 최대한 내용을 줄여 표현했습니다. (너무 길면 이해가 힘들고, 어느정도 수준이 되어야 이해가 되기 때문)
  • 혹시 궁금하시다면 위 링크를 참조 하시면 됩니다.

1. 기본 DART 프로그램

// 함수 정의 
printInteger(int aNumber) {
  print('The number is $aNumber.'); // 콘솔에 결과 출력
}

// 앱 진입점(초기 실행되는 구간)
main() {
  var number = 42; // 변수 선언 및 초기화
  printInteger(number); // 함수 호출 
}

2. 중요 컨셉

  • type 지정은 옵션 : 일반적으로 var 로 변수를 선언하면 알아서 runtime(프로그램 실행시) 이전에 추론에 의해 type(변수타입) 이 auto casting(추론 전환) 됩니다.
  • dart 는 List<int> 등과 같은 generic(총칭:제네릭) 타입을 지원
  • 중첩 함수 지원
  • Java와 달리 Dart에는 public, protected 및 private 키워드가 없습니다. _ 로 private 를 표현

3. 변수 선언 방식

아래 3가지 형태로 변수를 선언 할 수 있습니다. Var (가변), dynamic (동적), String(엄격하게 strict )

var name = 'Bob';

dynamic name = 'Bob';

String name = 'Bob';

4. 기본 값

  • 값을 할당하지 않으면 기본적으로 null 값을 가지게 됩니다.
int lineCount;
assert(lineCount == null);

참조 : assert 함수는 배포시(production)에서는 무시 됩니다. 개발하는 동안 debug 모드에서만 동작하며, 함수 내부 값이 일치하지 않으면 예외를 발생시킵니다. ( throws exception )

5. final 과 const

* 값이 변하지 않는 경우 `final` 또는 `const` 를 사용하면 됩니다.
* final : 값을 한번만 설정 가능
* const : 컴파일 시점에 상수가 됩니다. ( 암묵적으로는 final 임 )

인스턴스 변수(instance variable)는 final이 될 수 있지만 const는 사용할 수 없습니다. 최종 인스턴스 변수는 생성자 본문이 시작되기 전에 변수 선언, 생성자 매개 변수(constructor parameter) 또는 생성자의(constructor’s) 이니셜 라이저 목록에서 초기화되어야합니다.

final name = 'Bob'; // 주석 없이 사용된 경우
final String nickname = 'Bobby';

name = 'Alice'; // 오류 : final 변수는 1번만 설정 가능

const bar = 1000000;
const double atm = 1.01325 * bar;

6. 내장 타입

flutter 에서 지원하는 내장 타입 목록

  • numbers
  • strings
  • booleans
  • lists ( 타 언어에서는 배열(array)라고도 알려짐 )
  • maps
  • runes (유니코드 문자를 표현할 때 사용)
  • symbols

7. numbers (숫자)

  • int, double 사용 가능
  • int, double 둘 다 num 의 subtype(하위 타입)
// ex) int
var x = 1;
var hex = 0xDEADBEEF;

// ex) double
var y = 1.1;
var exponents = 1.42e5;

double z = 1; // double z = 1.0 과 동일

// 파싱 예제

// String -> int
var one = int.parse('1');
assert(one == 1);

// String -> double
var onePointOne = double.parse('1.1');
assert(onePointOne == 1.1);

// int -> String
String oneAsString = 1.toString();
assert(oneAsString == '1');

// double -> String
String piAsString = 3.14159.toStringAsFixed(2);
assert(piAsString == '3.14');

8. strings (문자열)

  • UTF-16 을 기본으로 사용
  • (쌍따옴표 : double quotes) 를 가지고 문자열을 생성
  • + 연산자를 사용하여 문자열을 연결
  • ( quote 홑따옴표 또는 double quotes 쌍따옴표 ) 세 개 를 사용하여 다중열을 표현 할 수 있다.
  • raw string 을 r’…’ 통해 표현 : unicode 문자를 표현할 수 있음 (특수문자 등) : Runes 참조
var s1 = 'Single quotes work well for string literals.';

var s2 = 'The + operator ' + 'works, as well.';

var s1 = '''
You can create
multi-line strings like this one.
''';

var s2 = """This is also a
multi-line string.""";

var s = r'In a raw string, not even \n gets special treatment.';
  • $를 통해 변수 또는 상수를 문자열 내부에서 치환하여 사용 할 수 있음
// const 문자열에서 사용 가능
const aConstNum = 0;
const aConstBool = true;
const aConstString = 'a constant string';

// const 문자열에서 사용 불가
var aNum = 0;
var aBool = true;
var aString = 'a string';
const aConstList = [1, 2, 3];

const validConstString = '$aConstNum $aConstBool $aConstString';
// const invalidConstString = '$aNum $aBool $aString $aConstList';

9. boolean (참거짓)

// 공백 문자열 점검 
var fullName = '';
assert(fullName.isEmpty);

// 0 체크 
var hitPoints = 0;
assert(hitPoints <= 0);

// null 체크 
var unicorn;
assert(unicorn == null);

// NaN 체크 : Not a Number 숫자 여부 체크
var iMeantToDoThis = 0 / 0;
assert(iMeantToDoThis.isNaN);

10. Lists (목록)

var list = [1, 2, 3];
assert(list.length == 3);
assert(list[1] == 2);

list[1] = 1;
assert(list[1] == 1);

var constantList = const [1, 2, 3];
// constantList[1] = 1; // 상수로 할당한 뒤 값을 변경 하려해서 오류 발생 

11. Maps ( 맵 : key, value 형태 )

var gifts = {
  // Key:    Value
  'first': 'partridge',
  'second': 'turtledoves',
  'fifth': 'golden rings'
};

var nobleGases = {
  2: 'helium',
  10: 'neon',
  18: 'argon',
};

var gifts = Map();
gifts['first'] = 'partridge';
gifts['second'] = 'turtledoves';
gifts['fifth'] = 'golden rings';

var nobleGases = Map();
nobleGases[2] = 'helium';
nobleGases[10] = 'neon';
nobleGases[18] = 'argon';

12. Runes (룬)

  • UTF-32 코드
  • heart character (♥) is \u2665
  • emoji (😆) is \u{1f600}.

13. Symbols (심볼)

Symbol 객체는 Dart 프로그램에서 선언 된 연산자 또는 식별자를 나타냅니다.

  • #을 붙여서 사용하면 됨
#radix
#bar

14. Functions (함수)

  • return 타입을 미지정 해도 됨 ( 추천하지는 않음 )
  • arrow function 사용 가능
  • 아래 함수는 모두 동일
bool isNoble(int atomicNumber) {
  return _nobleGases[atomicNumber] != null;
}

// 사용 가능하지만 return type 을 지정해 주는 것을 추천
isNoble(int atomicNumber) {
  return _nobleGases[atomicNumber] != null;
}

bool isNoble(int atomicNumber) => _nobleGases[atomicNumber] != null;

15. Optional parameters (선택 적 변수)

  • 두가지(Optional named parameters, optional positional function)를 동시에 섞어서 사용할 수는 없음
  • Optional named parameter 를 flutter에서 매우 많이 사용하므로 눈에 잘 익혀야 됨.

15.1 이름 옵션 파라미터 (Optional named parameters)

  • 모든 값은 옵션임
  • @required 어노테이션(annotation)을 통해 필수 입력 받도록 할 수 있음
  • 미 설정된 값은 기본값 null을 갖게 됨
// 함수 정의 시 { 파라미터1, 파라미터2 ... }
void enableFlags({bool bold, bool hidden}) {...}

// 함수 호출 시 ( 파라미터명: 값 ) 형태로 호출 
enableFlags(bold: true, hidden: false);

// @required 를 통해 반드시 값을 입력 받도록 처리 
const Scrollbar({Key key, @required Widget child})
  • 옵션 위치 함수 (optional positional function)

[]를 통해 값을 옵션으로 받아 처리 할 수 있다.

String say(String from, String msg, [String device]) {
  var result = '$from says $msg';
  if (device != null) {
    result = '$result with a $device';
  }
  return result;
}

// 파라미터 2개 
assert(say('Bob', 'Howdy') == 'Bob says Howdy');

// 파라미터 3개 
assert(say('Bob', 'Howdy', 'smoke signal') ==
    'Bob says Howdy with a smoke signal');

16. 기본 파라미터 값

  • = 을 통해 함수 입력 값의 기본 값을 지정할 수 있다.
///  [bold] 와 [hidden] 의 기본 값을 설정 
void enableFlags({bool bold = false, bool hidden = false}) {...}

// bold 참(true) hidden 는 거짓(false)이 됨
enableFlags(bold: true);
  • 위치 옵션함수 또한 기본값을 쓸 수 있음
String say(String from, String msg,
    [String device = 'carrier pigeon', String mood]) {
  var result = '$from says $msg';
  if (device != null) {
    result = '$result with a $device';
  }
  if (mood != null) {
    result = '$result (in a $mood mood)';
  }
  return result;
}

assert(say('Bob', 'Howdy') ==
    'Bob says Howdy with a carrier pigeon');

17. main() 함수

  • 앱의 진입 점임 ( entry point ) - top level function
  • 모든 앱은 반드시 main() 함수를 포함해야 됨
  • 옵션으로 List<String> 파라미터를 받을 수 있음
void main(List<String> arguments) {
  print(arguments);

  assert(arguments.length == 2);
  assert(int.parse(arguments[0]) == 1);
  assert(arguments[1] == 'test');
}

18. Functions as first-class objects

  • 함수에서 인자 값을 생략 할 수 있음
void printElement(int element) {
  print(element);
}

var list = [1, 2, 3];

// printElement 함수의 인자 값을 생략 할 수 있음
list.forEach(printElement);

// 위 함수와 동일한 결과를 보여준다
list.forEach(function(el){
    printElement(el);
});
  • 함수를 변수에 할당 할 수 있음
var loudify = (msg) => '!!! ${msg.toUpperCase()} !!!';
assert(loudify('hello') == '!!! HELLO !!!');

19. Anonymous functions (무기명 함수)

  • 람다(lamda) 또는 클로져(closure) 라고도 불리움
  • 코드가 더욱 간결해 짐
([[Type] param1[, …]]) { 
  codeBlock; 
}; 
var list = ['apples', 'bananas', 'oranges'];
list.forEach((item) {
  print('${list.indexOf(item)}: $item');
});

// 만약 함수가 1줄인 경우 아래와 같이 arrow function을 사용하면 더 짧아짐 
list.forEach((item) => print('${list.indexOf(item)}: $item'));

20. Lexical closures

클로저는 함수가 원래 범위 외부에서 사용되는 경우에도 어휘(lexical) 범위의 변수에 접근 할 수 있는 함수 객체입니다.

/// addBy 만큼 더해주는 함수를 리턴 해 줍니다.
Function makeAdder(num addBy) {
  return (num i) => addBy + i;
}

void main() {
  // 2를 더해주는 함수 생성
  var add2 = makeAdder(2);

  // 4를 더해주는 함수 생성
  var add4 = makeAdder(4);

  assert(add2(3) == 5);
  assert(add4(3) == 7);
}

21. 함수 결과 동일여부 테스트 방법

  • assert 를 적극 활용
void foo() {} // top-level 함수

class A {
  static void bar() {} // 정적 함수 
  void baz() {} // 인스턴스 함수
}

void main() {
  var x;

  // top-level 함수와 비교 
  x = foo;
  assert(foo == x);

  // 정적 함수 비교 
  x = A.bar;
  assert(A.bar == x);

  // 인스턴스 함수 비교
  var v = A(); // Instance #1 of A
  var w = A(); // Instance #2 of A
  var y = w;
  x = w.baz;

  // 동일 인스턴스 참조 
  // 결과는 동일 
  assert(y.baz == x);

  // 다른 인스턴스 참조 
  // 결과는 동일하지 않음
  assert(v.baz != w.baz);
}

맺음말

  • 고팍스 천하제일연재대회 진행안내 에 당첨되어 연재글을 시작합니다.

  • 구글에서 만든 언어 dart 와 이를 활용하는 모바일 앱 프레임워크 flutter 를 소개할 예정입니다.

  • 참고로 flutter는 구글의 차기 OS fuchsia 에서 메인으로 쓸 언어라고 하네요 :)

  • 궁금하신 점은 언제나 댓글로 문의 주시면 성심것 답글 드립니다.

  • 짧게 쓴다 했지만 내용이 많아서 자르고 다음 편으로 이어 집니다.

관련 글 링크

@flutters : 제가 작성한 글 중 fluter 관련 글만 모아서 리스팀 처리

설치/설정


aaronhong_banner.jpg

Sort:  

다트는 먼가 자바와 자바스크립트를 합쳐놓은 듯한 느낌이 드네요.
자바 개발자라면 금방 배울수 있을 것 같습니다. ㅎㅎ
저도 원사마님 블로그를 보면서 천천히 배우면서 따라가야겠습니다.
플러터 가즈아~!

15.1 이름 옵션 파라미터 (Optional named parameters)

이 부분이 새로운 부분이라 첨에 플러터 했을때 뭐징 ?! 그랬네요 ... 저도 이 글 작성하면서 아 ~ 그랬다는 ㅜㅜ

안피곤님도 리엑트 고수로 가즈아 ~ 나중에 한번에 몰아서 정독하겠습니다 :)

저는 봐도 이해를 못하는 수준이네요.^^
원사마님은 node-js와 data base setup쪽도 하시나요?

업무는 java인데 취미로 nodejs도 하네요 :)

스팀잇 하면서 봇같은거 만들면서 배우게 되서요

db는 oracle mysql postgresql mongodb 써보긴 했죠 :)

요즘은 하나만 하면 먹고살기 힘들어서 ㅋㅋ

Posted using Partiko Android

저는 그쪽엔 전문지식이 없어서...^^
정확히 같은 일인지는 모르겠지만
디커머스 쪽 댑에 혹 관심이 있으실까...해서 질문 드려 봤어요.^^

에고고 눈이 뱅글뱅글 돌아갑니다.

ㅜㅜ 비 개발자가 보기엔 힘들지용 :) 하지만 관심 있으시면 그냥 한번 봐보세요 ㅎㅎ

눈이 뱅글 거려도 또 봐봤습니다. 알려고 노력을 해봤답니다.

공부다 공부!!

fluter 로 스트리밍 플레이어 만들고 싶어요~

헬로님 책 많이 사셨으니 저보다 고수시자나요 :) ㅋㅋㅋ

Hi @wonsama!

Your post was upvoted by @steem-ua, new Steem dApp, using UserAuthority for algorithmic post curation!
Your UA account score is currently 3.809 which ranks you at #4637 across all Steem accounts.
Your rank has improved 36 places in the last three days (old rank 4673).

In our last Algorithmic Curation Round, consisting of 281 contributions, your post is ranked at #208.

Evaluation of your UA score:
  • You're on the right track, try to gather more followers.
  • The readers like your work!
  • Try to work on user engagement: the more people that interact with you via the comments, the higher your UA score!

Feel free to join our @steem-ua Discord server