[flutter] Dart의 Nullability는 무엇입니까 (기본적으로 Null을 사용할 수 없음)?

나는 현재 ” Null을 허용하지 않는”실험 인 새로운 Dart null 안전 언어 기능에 대해 들었습니다 . 소개 할 예정이다 nullable이 아닌 기본적으로 .

기능 사양은 여기 및 언어 GitHub 문제는 여기에 있습니다 .

어떻게 작동하며 어디에서 시도 할 수 있습니까?



답변

널 입력 불가 (기본적으로)

널 입력 불가능 (기본적으로) 실험 은 현재 nullsafety.dartpad.dev 에서 찾을 수 있습니다 . 여기
에서 전체 사양전체 로드맵을 읽을 수 있습니다 .


기본적으로 널 입력 불가 란 무엇을 의미합니까?

void main() {
  String word;
  print(word); // illegal

  word = 'Hello, ';
  print(word); // legal
}

위에서 볼 수 있듯이 기본적으로 변수가 널 입력 가능 하지 않다는 것은 정상적으로 선언 된 모든 변수가 될 수 없음을 의미 합니다 null. 따라서 변수가 할당되기 전에 변수에 액세스하는 작업은 불법입니다.
또한 null널 입력 불가능 변수에 지정하는 것도 허용되지 않습니다.

void main() {
  String word;

  word = null; // forbidden
  world = 'World!'; // allowed
}

이것이 어떻게 도움이 되나요?

변수가 널 입력 가능하지 않으면 결코 변수가 아닌지 확인할 수 있습니다 null. 따라서 사전에 확인할 필요가 없습니다.

int number = 4;

void main() {
  if (number == null) return; // redundant

  int sum = number + 2; // allowed because number is also non-nullable
}

생각해 내다

클래스의 인스턴스 필드가 널 입력 가능하지 않은 경우 초기화해야합니다 .

class Foo {
  String word; // forbidden

  String sentence = 'Hello, World!'; // allowed
}

late이 동작을 수정하려면 아래를 참조하십시오 .

널 입력 가능 유형 ( ?)

변수 유형에 물음표 를 추가하여 널 입력 가능 유형 을 사용할 수 있습니다 ?.

class Foo {
  String word; // forbidden

  String? sentence; // allowed
}

널 (NULL) 사용하기 전에 변수를 초기화 할 필요가 없습니다. null기본적으로 초기화됩니다 .

void main() {
  String? word;

  print(word); // prints null
}

!

덧붙이 !어떤 변수 것은 e던져 것입니다 런타임 오류가 있는 경우 e널 (null)이고 그렇지 않으면로 변환 비 – 널 (NULL)v.

void main() {
  int? e = 5;
  int v = e!; // v is non-nullable; would throw an error if e were null

  String? word;
  print(word!); // throws runtime error if word is null

  print(null!); // throws runtime error
}

late

키워드 는 선언 될 때가 아니라 액세스 될 때 나중에 초기화late 될 변수를 표시하는 데 사용할 수 있습니다 . 이는 또한 나중에 초기화 할 수있는 널 입력 불가능 인스턴스 필드 를 가질 수 있음을 의미합니다 .

class ExampleState extends State {
  late String word; // non-nullable

  @override
  void initState() {
    super.initState();

    // print(word) here would throw a runtime error
    word = 'Hello';
  }
}

word초기화되기 전에 액세스 하면 런타임 오류가 발생합니다.

late final

최종 변수는 이제 늦게 표시 할 수 있습니다.

late final int x = heavyComputation();

여기에 heavyComputation한 번만 x액세스 하면 호출됩니다 . 또한 late final이니셜 라이저없이 late변수를 선언하는 것과 동일 하지만 선언 할 수는 없지만 한 번만 지정할 수 있습니다.

late final int x;
// w/e
x = 5; // allowed
x = 6; // forbidden

이니셜 라이저가있는 모든 최상위 또는 정적 변수는 이제 변수에 late관계없이 평가 됩니다 final.

required

이전에는 주석 ( @required)으로 수정 자에 내장되어 있습니다. (함수 또는 클래스의 경우) 명명 된 매개 변수를로 표시 할 수 있습니다 required.

void allowed({required String word}) => null;

이는 또한 매개 변수가 널 입력 가능하지 않아야하는 경우 이를 표시 required하거나 기본값을 가져야 함을 의미합니다.

void allowed({String word = 'World'}) => null;

void forbidden({int x}) // compile-time error because x can be null (unassigned)
    =>
    null;

다른 명명 된 매개 변수는 널 입력 가능해야합니다 .

void baz({int? x}) => null;

?[]

널 인식 ?[]연산자가 색인 연산자에 추가되었습니다 [].

void main() {
  List<int>? list = [1, 2, 3];

  int? x = list?[0]; // 1
}

구문 결정에 대한이 기사를 참조하십시오 .

?..

계단식 연산자에는 이제 새로운 null 인식 연산자가 ?..있습니다.

받는 사람이 null아닌 경우에만 다음 캐스케이드 작업이 실행됩니다 . 따라서 ?..캐스케이드 순서에서 첫 번째 캐스케이드 연산자 여야합니다.

void main() {
  Path? path;

  // Will not do anything if path is null.
  path
    ?..moveTo(3, 4)
    ..lineTo(4, 3);

  // This is a noop.
  (null as List)
    ?..add(4)
    ..add(2)
    ..add(0);
}

Never

혼동을 피하기 위해 : 이것은 개발자가 걱정해야 할 것이 아닙니다. 완전성을 위해 언급하고 싶습니다.

Never이전에 기존과 같은 형태가 될 것입니다 Null( 하지null 에 정의) dart:core. 이 두 클래스 모두 확장, 구현 또는 혼합 할 수 없으므로 사용하도록 의도되지 않았습니다.

기본적으로 Never유형이 허용 Never되지 않으며 자체 인스턴스화 할 수 없음을 의미합니다 .
아무것도하지만 NeverA의 List<Never>가 있다는 것을 의미 목록의 만족 제네릭 형식 제약 조건 이어야 . List<Null>그러나 다음을 포함 할 수 있습니다 null.

// Only valid state: []
final neverList = <Never>[
  // Any value but Never here will be an error.
  5, // error
  null, // error

  Never, // not a value (compile-time error)
];

// Can contain null: [null]
final nullList = <Null>[
  // Any value but Null will be an error.
  5, // error
  null, // allowed

  Never, // not a value (compile-time error)
  Null, // not a value (compile-time error)
];

예 : 컴파일러는 empty를 유추 List<Never>합니다 . 내가 걱정하는 한 프로그래머가 사용하지 않아야합니다. const List<T>
Never


답변