null_closures: 클로저가 기대되는 자리에 null을 넘기지 마세요
null_closures: 클로저가 기대되는 자리에 null을 넘기지 마세요
메서드에 넘기는 클로저는 조건부로만 호출되는 경우가 많아서, 테스트나 "정상 경로"의 프로덕션 호출에서는 null이 넘어가도 문제가 드러나지 않아요. 그러다 실제로 클로저가 호출되는 순간에 갑자기 예외가 터지고요. null_closures는 클로저가 기대되는 자리에 null 리터럴을 넘기는 걸 미리 잡아주는 린트(lint) 규칙이에요.
출처: null_closures
본문
상세 설명
클로저(closure)가 기대되는 자리에 null을 인자로 넘기지 마세요. 이 규칙은 다음과 같은 위치에서 클로저가 기대되는 곳에 null 리터럴을 넘기는 경우만 잡아줘요.
생성자
dart:async에서Future의 0번째 위치 인자Future.microtask의 0번째 위치 인자Future.sync의 0번째 위치 인자Timer의 0번째 위치 인자Timer.periodic의 1번째 위치 인자
dart:core에서List.generate의 1번째 위치 인자
정적 함수
dart:async에서scheduleMicrotask의 0번째 위치 인자Future.doWhile의 0번째 위치 인자Future.forEach의 0번째 위치 인자Future.wait의 named 인자cleanupTimer.run의 0번째 위치 인자
인스턴스 메서드
dart:async에서Future.then의 0번째 위치 인자Future.complete의 0번째 위치 인자
dart:collection에서Queue.removeWhere의 0번째 위치 인자Queue.retainWhere의 0번째 위치 인자Iterable.firstWhere의 0번째 위치 인자와 named 인자orElseIterable.forEach의 0번째 위치 인자Iterable.fold의 1번째 위치 인자Iterable.lastWhere의 0번째 위치 인자와 named 인자orElseIterable.map의 0번째 위치 인자Iterable.reduce의 0번째 위치 인자Iterable.singleWhere의 0번째 위치 인자와 named 인자orElseIterable.skipWhile의 0번째 위치 인자Iterable.takeWhile의 0번째 위치 인자Iterable.where의 0번째 위치 인자List.removeWhere의 0번째 위치 인자List.retainWhere의 0번째 위치 인자String.replaceAllMapped의 1번째 위치 인자String.replaceFirstMapped의 1번째 위치 인자String.splitMapJoin의 named 인자onMatch와onNonMatch
BAD:
[1, 3, 5].firstWhere((e) => e.isOdd, orElse: null);
GOOD:
[1, 3, 5].firstWhere((e) => e.isOdd, orElse: () => null);
null 대신 실제로 호출될 수 있는 클로저를 넘겨주면 됩니다.
활성화하기
null_closures 규칙을 활성화하려면 analysis_options.yaml 파일의 linter > rules 아래에 null_closures를 추가해요.
linter:
rules:
- null_closures
대신 YAML map 문법으로 린터 규칙을 설정한다면, linter > rules 아래에 null_closures: true를 추가해요.
linter:
rules:
null_closures: true
참고로 이 규칙은 권장(Recommended) 규칙이고 자동 수정(fix)이 제공돼요.