Dart callback null 처리하기
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'}); }