2 minute read

Dart function null 체크하여 다른 값 넣기

Dart로 Flutter를 개발하다 보면 종종 파라미터로 받은 콜백을 직접 호출해야 할 때가 있음

하지만 callback을 null 체크를 하지 않으면 NoSuchMethodError가 발생할 것임

The following NoSuchMethodError was thrown while handling a gesture:
The method ‘call’ was called on null.
Receiver: null
Tried calling: call()

dart로 간단한 구현 예제를 만들어 상황 별 null 처리에 대해 정리함

⚠⚠⚠
아래에 작성한 모든 처리는 if(callback != null) callback()과 같은 결과이므로,
기존에 이렇게 처리를 하고 있는 경우에는 포스팅이 불필요 할 수 있음

1. callback이 있으면 호출하고 없으면 아무것도 하지 않을 때

void callbackNullHandlingTest1({Function callback}) {
   callback?.call();
}

2. callback이 return 값이 있고, null 처리하고 싶을 때

void callbackNullHandlingTest2_1({String Function() callback}) {
  final message = callback?.call() ?? 'callback is null!';
  print(message);
}

// 결과: callback is null!
void callbackNullHandlingTest2_2({String Function() callback}) {
  defaultMessage() => 'default message!';
  final message = callback?.call() ?? defaultMessage();
  final message2 = (callback ?? defaultMessage).call();
  print(message);
  print(message2);
}

// 결과: default message!
// 결과: default message!

3. callback return 타입이 void이고, null이면 다른 메서드를 호출하고 싶을 때

(2)의 callback?.call() ?? defaultFunction()와 같이 사용하게 되면 expression error가 발생함

This expression has a type of ‘void’ so its value can’t be used.

Try checking to see if you’re using the correct API; there might be a function or call that returns void you didn’t expect. Also check type parameters and variables which might also be void.

매개변수가 없을 때

  • (2)에서 두 번째 방식처럼 사용
void callbackNullHandlingTest3_1({void Function() callback}) {
  defaultFunction() => print('default function!');
  (callback ?? defaultFunction).call();
}

// 결과: default function!
  • Function.apply 사용
void callbackNullHandlingTest3_2({void Function() callback}) {
  defaultFunction() => print('default function!');
  Function.apply(callback ?? defaultFunction, null);
}

// 결과: default function!

매개변수가 있을 때

  • positional parameters일 때
void callbackNullHandlingTest3_3({void Function(String a, String b) callback}) {
  defaultFunction(String a, String b) => print('$a, $b!');
  (callback ?? defaultFunction).call('Hi', 'Bob');
  Function.apply(callback ?? defaultFunction, ['Hi', 'Bob']);
}

// 결과: Hi, Bob!
  • named parameters일 때
void callbackNullHandlingTest3_4({void Function({String message, String name}) callback}) {
  defaultFunction({String message, String name}) => print('$message, $name!');
  (callback ?? defaultFunction).call(message: 'Hello', name: 'John Doe');
  Function.apply(callback ?? defaultFunction, null, {Symbol('message'): 'Hello', Symbol('name'): 'John Doe'});
}

// 결과: Hello, John Doe!
👀전체 코드 보기
void main() {
  callbackNullHandlingTest1(callback: null);
  callbackNullHandlingTest2_1(callback: null);
  callbackNullHandlingTest2_2(callback: null);
  callbackNullHandlingTest3_1(callback: null);
  callbackNullHandlingTest3_2(callback: null);
  callbackNullHandlingTest3_3(callback: null);
  callbackNullHandlingTest3_4(callback: null);
}

void callbackNullHandlingTest1({Function callback}) {
  callback?.call();
}

void callbackNullHandlingTest2_1({String Function() callback}) {
  final message = callback?.call() ?? 'callback is null';
  print(message);
}

void callbackNullHandlingTest2_2({String Function() callback}) {
  defaultMessage() => 'default message!';
  final message = callback?.call() ?? defaultMessage();
  final message2 = (callback ?? defaultMessage).call();
  print(message);
  print(message2);
}

void callbackNullHandlingTest3_1({void Function() callback}) {
  defaultFunction() => print('default function!');
  (callback ?? defaultFunction).call();
}

void callbackNullHandlingTest3_2({void Function() callback}) {
  defaultFunction() => print('default function!');
  Function.apply(callback ?? defaultFunction, null);
}

void callbackNullHandlingTest3_3({void Function(String a, String b) callback}) {
  defaultFunction(String a, String b) => print('$a, $b!');
  (callback ?? defaultFunction).call('Hi', 'Bob');
  Function.apply(callback ?? defaultFunction, ['Hi', 'Bob']);
}

void callbackNullHandlingTest3_4({void Function({String message, String name}) callback}) {
  defaultFunction({String message, String name}) => print('$message, $name!');
  (callback ?? defaultFunction).call(message: 'Hello', name: 'John Doe');
  Function.apply(callback ?? defaultFunction, null, {Symbol('message'): 'Hello', Symbol('name'): 'John Doe'});
}

Updated: