나는 현재 ” 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
되지 않으며 자체 인스턴스화 할 수 없음을 의미합니다 .
아무것도하지만 Never
A의 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