Post

[Dart] 1. 함수

※ https://dart-ko.dev/language/functions#the-main-function 을 참고하여 작성하였습니다.

  • 기본 함수 구현

    • return 타입 명시: bool

      1
      2
      3
      
      bool isNoble(int atomicNumber){
      		return _nobleGases[atomicNumber] != null;
      }
      
    • return 타입 명시 X: bool이 없어도 작동됨, 하지만 타입 명시를 권장

      1
      2
      3
      
      isNoble(atomicNumber){
      		return _nobleGases[atomicNumber] != null;
      }
      
    • 하나의 표현식 만을 가지는 함수: ⇒ 를 사용

      1
      
      bool isNoble(int atomicNumber) => _nobleGases[atomicNumber] != null;
      
  • 매개변수

    • named 매개변수

      [형식] {매개변수1, 매개변수2, …}

      • defualt 값이 없으면

        → void enableFlags({bool? bold, bool? hidden}) 처럼 자료형을 nullable(?) 로 지정해야 함

        → 함수 호출: enableFlags(bold: true, hidden: false);

      • default 값이 있으면

        → void enableFlags({bool bold= false, bool hidden= false}) { … }

        → 함수 호출: enableFlags(bold: true);

      optional positional 매개변수

      [형식] [매개변수1, 매개변수 2, …]

      • 역시, default 값이 없으면 자료형을 nullable(?)로 선언해야 함

      • default 값이 있으면,

        → default 값은 반드시!! 컴파일 타임 상수로 지정되어야 함

    • required positional 매개변수

  • main() 함수

    • Explanation

      • 최상위 함수
      • void 반환
    • optional List의 매개변수를 가짐

      1
      2
      3
      
      void main(List<String> arguments){
      		print(arguments);
      }
      
  • 일급 객체로서의 함수

    • 함수의 인자에 함수(printElement)를 넘기는 것이 가능
    1
    2
    3
    4
    5
    6
    7
    
    void printElement(int element){
    		print(element);
    }
      
    var list= [1, 2, 3];
      
    list.forEach(printElement);
    
    • 변수에 함수의 할당이 가능 → 익명 함수
      • msg: 함수의 인수
    1
    2
    
    var loudify= (msg)=> '!!!{msg.toUpperCase()}!!!';
    assert(loudify('hello') == '!!!HELLO!!!');
    
  • 익명 함수

    • Explanation

      • 이름이 없는 함수

        이름이 없는 함수: 익명 함수, 람다, 클로져

      • 위의 loudify의 변수처럼,

        익명 함수를 변수에 선언해서 컬렉션에 추가/제거 하는 것도 가능!

    • 예제 1) 전체 과정

      1
      2
      3
      4
      5
      6
      7
      8
      
      void main(){
      		const list= ['apples', 'bananas', 'oranges'];
      		list.map((item) {
      				return item.toUpperCase();
      		}).forEach((item) {
      				print('$item: ${item.length}');
      		});
      }
      
    • 예제 2) => 사용

      1
      2
      3
      4
      5
      
      void main(){
      		const list= ['apples', 'bananas', 'oranges'];
      		list
      				.map((item) => item.toUpperCase())
      				.forEach((item) => print('$item: ${item.length}'));
      
  • 렉시컬 스코프(lexically scoped)

    • Explanation

      • 변수가 선언된 위치에 따라 그 변수를 사용할 수 있는 범위가 정해지며,

        내부 함수는 외부 함수의 변수에 접근할 수 있음

      • 변수의 범위를 확인하고 싶다면→ 중괄호의 끝을 따라가기

    • 예시> 최상위 수준까지 모든 수준의 변수 사용이 가능

  • 렉시컬 클로저

    • 클로저: 함수와 함수가 정의된 환경을 묶는 것

      • 일반 함수의 클로저: 함수가 정의된 스코프의 변수를 기억하는 함수 객체
      • 인스턴스 메서드의 클로저: 인스턴스와 함께 묶인 메서드
    • 클로저 함수

      • 클로저 함수 자신이 정의된 스코프를 기억함
      • 클로저는 함수가 생성될 때의 변수를 기억하고 접근할 수 있음
    • 예제

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      
      Function makeAdder(int addBy) {
      		return (int i) => addBy + i;
      }
          
      void main() {
      		var add2 = makeAdder(2); // (int i) => 2+i 를 가진 add2(클로저)
      		var add4 = makeAdder(4); // (int i) => 4+i 를 가진 add4(클로저)
          
      		assert(add2(3) == 5); // 3를 add2의 인자로 받아 참
      		assert(add4(3) == 7);  // 3을 add4의 인자로 받아 참
      }
      
      • assert()는 조건식이 참이면 아무것도 출력되지 않고,

        거짓일 경우 예외를 발생시킴

  • 동등성 테스트 함수

    • assert(함수1 == 함수2)
    • 함수: 최상위 함수, 정적 함수, 인스턴스 함수의 동등성 확인
  • 반환 값

    • 반환 값이 명시되어 있지 않은 경우: 암묵적으로 return null; 을 명시

      1
      2
      
      foo() {}
      assert(foo() == null);
      
    • 두 개 이상의 값을 반환

      1
      2
      3
      
      (String, int) foo(){
      		return ('something', 42);
      }
      
  • 제너레이터 함수

    • Explanation

      • 데이터의 시퀀스를 지연하여(lazily) 생성하고 싶을 때 제너레이터 함수 사용
    • 동기식 제너레이터

      • Iterable 객체 반환
      • 함수의 바디: sync*
      • 함수의 호출: for
      1
      2
      3
      4
      
      Iterable<int> naturalsTo(int n) sync* {
        int k = 0;
        while (k < n) yield k++;
      }
      
    • 비동기식 제너레이터: Stream 객체 반환

      • Stream 객체 반환
      • 함수의 바디: async*
      • 호출: awiat for
      1
      2
      3
      4
      
      Stream<int> asynchronousNaturalsTo(int n) async* {
        int k = 0;
        while (k < n) yield k++;
      }
      
    • 재귀를 이용한 제너레이터

      1
      2
      3
      4
      5
      6
      
      Iterable<int> naturalsDownFrom(int n) sync* {
        if (n > 0) {
          yield n;
          yield* naturalsDownFrom(n - 1);
        }
      }
      
This post is licensed under CC BY 4.0 by the author.