ããã«ã¡ã¯ãHabrïŒç§ã®ã³ã¡ã³ããšãšãã«ãFilipHracekã«ããèšäºãAnnouncingsoundnullsafetyãã®ç¿»èš³ãããªãã®æ³šæãåèµ·ããŸãïŒNullsafety-ããŒãããŒã ã«ãšã£ãŠéèŠãªã¹ããããããã«ã»ãŒããã£éçºã®æè¡ãã¬ãã¥ãŒã®ãã¬ãŒã³ããŒã·ã§ã³ã§å®çŸããŸããããã«ã»ãŒããã£ã¯ãæ€åºãå°é£ãªããšãå€ãã¯ã©ã¹å šäœã®ãã°ãåé¿ããããŒãã¹ãšããŠãããã©ãŒãã³ã¹ãå€§å¹ ã«åäžãããŸããçŸæç¹ã§ã¯ãäºåçãªãã¯ãã«ã«ãã¬ãã¥ãŒããªãªãŒã¹ããŠããããã£ãŒãããã¯ããåŸ ã¡ããŠããŸãã
空ã®ãªã³ã¯ã§ã®å®å šãªäœæ¥ãããã«æ¬æã§ã¯ãç°¡æœã«ãããããããã³çšèªã®å®å®æ§ã®ããã«ãè±èªånullãnullå®å šæ§ã䜿çšãããŸãããããŠãããŒãã»ãã¥ãªãã£ããšãã翻蚳ã¯ãå®å šã«å察ã®èãã«ã€ãªãããŸãã
ãµãŠã³ã-ãã®ã³ã³ããã¹ãã§ã¯ïŒãµãŠã³ããã«ã®å®å šæ§ïŒã¯ãä¿¡é Œã§ããããšè§£éã§ããŸãã
ç¿»èš³ãæ¹åããããã®ææ¡ãããå ŽåããŸãã¯ãšã©ãŒãèŠã€ãã£ãå Žåã¯ãå人çãªã¡ãã»ãŒãžãæžã蟌ãã§ãã ãããä¿®æ£ã詊ã¿ãŸãã
ãã®èšäºã§ã¯ããã«ã»ãŒããã£ãå±éããDartããŒã ã®èšç»ãæããã«ãããµãŠã³ããã«ã»ãŒããã£ãšããçšèªã®èåŸã«ãããã®ãšããã®ã¢ãããŒããä»ã®ããã°ã©ãã³ã°èšèªãšã©ã®ããã«ç°ãªããã説æããŸãã
説æãããŠããããŒãžã§ã³ã¯ã2020幎6æ10æ¥ã«çºè¡šãããŸããã
ãªãå®å šæ§ããªãã®ã§ããïŒ
Dartã¯ã¿ã€ãã»ãŒããªèšèªã§ããããã¯ãããã¿ã€ãã®å€æ°ãååŸãããšãã³ã³ãã€ã©ãŒããã®å€æ°ã«å±ããããšãä¿èšŒã§ããããšãæå³ããŸãããã ããåã®å®å šæ§ã ãã§ã¯ã倿°ãnullã§ãªãããšã¯ä¿èšŒãããŸããã
ãã«ãšã©ãŒã¯äžè¬çã§ããGitHubã§æ€çŽ¢ãããšãDartã³ãŒãã®nullå€ã«ãã£ãŠåŒãèµ·ããããäœåãã®ã¬ããŒãïŒåé¡ïŒãèŠã€ããããããã®åé¡ã解決ããããšããã³ããããããã«å¢ããŸãã
次ã®äŸã§ããã«ãªã³ã¯ã®åé¡ãèŠã€ããŠãã ããã
void printLengths(List<File> files) {
for (var file in files) {
print(file.lengthSync());
}
}
ãã®é¢æ°ã¯ããŒãã®ãã©ã¡ãŒã¿ãŒã§åŒã³åºãããå Žåã¯ç¢ºãã«å€±æããŸãããèæ ®ãã¹ã2çªç®ã®ã±ãŒã¹ããããŸãã
void main() {
// Error case 1: passing a null to files.
printLengths(null);
// Error case 2: passing list of files, containing a null item.
printLengths([File('filename1'), File('filename2'), null]);
}
ãã«ã»ãŒããã£ã¯ãã®åé¡ãä¿®æ£ããŸãã
ãã«ã»ãŒããã£ã䜿çšãããšãããèªä¿¡ãæã£ãŠã³ãŒããä¿¡é Œã§ããŸããå®è¡æã«ç¡å¹åããã倿°ã«ã¢ã¯ã»ã¹ãããšããç ©ããããšã©ãŒã¯ãããããŸãããã³ã³ãã€ã«æã®éçãšã©ãŒã®ã¿ã
å®å šã«æ£çŽã«èšããšãçŸåšã®å®è£ ã§ã¯ãå®è¡æã«nullãšã©ãŒããã£ããããæ©äŒãããã€ãæ®ã£ãŠããŸããããããã«ã€ããŠã¯åŸã§è©³ãã説æããŸãã
å¥å šãªïŒä¿¡é Œã§ããïŒãã«ã®å®å šæ§
ããŒãã®ãã«ã»ãŒããã£ã®å®è£ ã¯å¥å šã§ããäžèšã®äŸã䜿çšããŠåæãããšãDartã³ã³ãã€ã©ã¯ããã¡ã€ã«ã®é åãšãã®äžã®èŠçŽ ãnullã«ãªããªãããšã100ïŒ ç¢ºä¿¡ããŠããããšãæå³ããŸãã Dartã³ã³ãã€ã©ãã³ãŒããåæãã倿°ãnullã§ãªãããšã確èªãããšããã®å€æ°ã«ã¯åžžã«å€ããããŸãããããã¬ã§å®è¡å¯èœãªã³ãŒãã確èªãããšãå®è¡æã«ãŒãã«ãªãå¯èœæ§ããŸã£ãããªãããšãããããŸãã ãä¿¡é Œæ§ã®é«ããå®è£ ã§ã¯ãªããå®è¡æã«å€ã®ååšããã§ãã¯ããå¿ èŠããããŸããä»ã®èšèªãšã¯ç°ãªããDartã¯å®è£ ã®ä¿¡é Œæ§ãSwiftãšå ±æããŠããŸãã
, , , null safety . Swift, Kotlin Dart. .Dartã§ã®ãã«ã»ãŒããã£ã®ãã®å ç¢ãªå®è£ ã«ã¯ããã1ã€ã®åªããçµæããããŸããã€ãŸããããã°ã©ã ãããå°ãããããéãããããšãã§ããŸããDartã¯ã倿°ãç¡å¹ã«ãªããªãããã«ãããããã³ã³ãã€ã«çµæãæé©åã§ããŸããããšãã°ãAOTã³ã³ãã€ã©ã¯ã空ã®åç §ã®ãã§ãã¯ã远å ããå¿ èŠããªããããããå°ããé«éãªãã€ãã£ãã³ãŒããçæã§ããŸãã
ããã€ãã®éåžžã«ææãªäºåçãªçµæãèŠãŠããŸãããããšãã°ãFlutterãã¬ãŒã ã¯ãŒã¯ã®äžè¬çãªã¬ã³ããªã³ã°ãã¿ãŒã³ããšãã¥ã¬ãŒããããã€ã¯ããã³ãããŒã¯ã§19ïŒ ã®ããã©ãŒãã³ã¹ã®åäžãèŠãããŸããã
åºæ¬åå
ãã«å®å šæ§ã®è©³çްãªèšèšã«é²ãåã«ãããŒãããŒã ã¯3ã€ã®åºæ¬ååãå®çŸ©ããŸãã
ãããã©ã«ãã§ã¯é ãã«å¯èœæ§ã/ **ããã¯ãããã¥ã¡ã³ãã§ã¯NNBDã®çç¥åœ¢ãšèŠãªãããããšããããããŸã** /倿°ãç¡å¹åã§ããããšãDartã«æç€ºçã«æç€ºããªãå Žåãç¡å¹åã§ããªããšèŠãªãããŸãã APIã§ã¯ãçŸåšãŒã以å€ã®å€ãæãäžè¬çã§ããããšãããã£ãããããããããã©ã«ããšããŠéžæããŸããã/ **ããã¯ããããçŸåšã®FlutterAPIã®äœãçŽãã§ã** /ã
段éçãªé©çšæ§..ããã«ã»ãŒããã£ã«æ®µéçã«ç§»è¡ããå¯èœæ§ãããããšãçè§£ããŠããŸããå®éãåããããžã§ã¯ãã«nullå¯èœããã³nullã®å®å šã³ãŒããå¿ èŠã§ãããã®ããã«ãã³ãŒãã®ç§»è¡ã«åœ¹ç«ã€ããŒã«ãæäŸããäºå®ã§ãã
å®å šãªä¿¡é Œæ§ïŒé³ïŒãäžèšã®ããã«ãããŒãã®ãã«ã»ãŒããã£ã¯å®å šã§ãããããžã§ã¯ãå šäœãšäŸåé¢ä¿ãnullã»ãŒããã£ã«å€æãããšãä¿¡é Œæ§ã®ãã¹ãŠã®ã¡ãªãããåŸãããŸãã
å®å šæ§ããªã倿°ã®å®£èš
åºæ¬çãªæ§æã¯ååã«åçŽã§ãã以äžã¯ãããŸããŸãªå€æ°ã宣èšããäŸã§ããnulläžå¯èœãªå€æ°ãããã©ã«ãã§äœ¿çšããããããåãããã«èŠããŸãããå€ãç¡å¹ã«ããããšã¯ã§ããŸããã
// In null-safe Dart, none of these can ever be null.
var i = 42;
final b = Foo();
String m = '';
Dartã¯ãäžèšã®å€æ°ã®ãããã«ãnullãå²ãåœãŠãªãããã«ããŸãã1000è¡åŸã§ãi = nullãå®è¡ããããšãããšãéçåæãšã©ãŒãšèµ€ãæ³¢ç·ãçºçããŸããããã°ã©ã ã¯ã³ã³ãã€ã«ãæåŠããŸãã
倿°ãnullå¯èœã«ãããå Žåã¯ããïŒãã䜿çšã§ããŸãããã®ãããªïŒ
// These are all nullable variables.
int? j = 1; // Can be null later.
final Foo? c = getFoo(); // Maybe the function returns null.
String? n; // Is null at first. Can be null at any later time, too
äžèšã®å€æ°ã¯ãçŸåšã®ããŒãžã§ã³ã®Dartã®ãã¹ãŠã®å€æ°ãšãŸã£ããåãããã«åäœããŸãã
'ïŒ' 'ã¯ä»ã®å Žæã§ã䜿çšã§ããŸãïŒ
// In function parameters.
void boogie(int? count) {
// It's possible that count is null.
}
// In function return values.
Foo? getFoo() {
// Can return null instead of Foo.
}
// Also: generics, typedefs, type checks, etc.
// And any combination of the above.
ããããç¹°ãè¿ãã«ãªããŸããããïŒãã䜿çšããå¿ èŠãã»ãšãã©ãªãããšãé¡ã£ãŠããŸãã倿°ã®å€§éšåã¯nulläžå¯ã«ãªããŸãã
ãã«ã»ãŒããã£ã䜿ãããããã
DartããŒã ã¯ãnullã®å®å šæ§ãå¯èœãªéã䜿ããããããããã«æžåœã«åãçµãã§ããŸããããšãã°ãnullããã¹ãããããã«ifã䜿çšããæ¬¡ã®ã³ãŒããèŠãŠãã ããã
void honk(int? loudness) {
if (loudness == null) {
// No loudness specified, notify the developer
// with maximum loudness.
_playSound('error.wav', volume: 11);
return;
}
// Loudness is non-null, let's just clamp it to acceptable levels.
_playSound('honk.wav', volume: loudness.clamp(0, 11));
}
Dartã¯ãifã¹ããŒãã¡ã³ããæž¡ããŸã§ã«ã©ãŠããã¹ãnullã«ããããšã¯ã§ããªãããšãçè§£ããã®ã«ååè³¢ãããšã«æ³šæããŠãã ããããã®ãããããŒãã䜿çšãããšãã¿ã³ããªã³ã§äžå¿ èŠã«èžãããšãªããclampïŒïŒã¡ãœãããåŒã³åºãããšãã§ããŸãããã®äŸ¿å©ãã¯ããããããããŒåæã«ãã£ãŠæäŸãããŸããDartããŒãµãŒã¯ãã³ãŒããå®è¡ããŠãããã®ããã«ã³ãŒãã調ã¹ãã³ãŒãã«é¢ãã詳现æ å ±ãèªåçã«ææ¡ããŸãã
Flow analysis, Dart, , , . null safety, :
foo(dynamic str) {
if (str is String) {
// dynamic length,
// String
print(str.length);
}
}
, Dart , null, :
int sign(int x) {
// The result is non-nullable.
int result;
if (x >= 0) {
result = 1;
} else {
result = -1;
}
// By this point, Dart knows the result cannot be null.
return result;
}
- (, result = -1;), Dart , result â , .ãããŒåæã¯ã颿°å ã§ã®ã¿æ©èœããŸããã°ããŒãã«å€æ°ãŸãã¯ã¯ã©ã¹ãã£ãŒã«ããããå ŽåãDartã¯å€ãããã«å²ãåœãŠãããããšãä¿èšŒã§ããŸãããDartã¯ãã¢ããªã±ãŒã·ã§ã³å šäœã®å®è¡ãããŒãã·ãã¥ã¬ãŒãããããšã¯ã§ããŸããããã®ããã倿°ãæåã«ã¢ã¯ã»ã¹ããããšãã«åæåãããããšãããã£ãŠããå Žåã¯ãæ°ããlateããŒã¯ãŒãã䜿çšã§ããŸããã宣èšããããšãã«åæåããããšã¯ã§ããŸããã
class Goo {
late Viscosity v;
Goo(Material m) {
v = m.computeViscosity();
}
}
æåã¯é¢ä¿ãããŸããããvããŒãã«ããããšã¯ã§ããªãããšã«æ³šæããŠãã ãããDartã¯ããŒã以å€ã®å€ãå²ãåœãŠãããã³ãŒãããšã©ãŒãªãã§ã³ã³ãã€ã«ããããŸã§ãvãèªã¿åãããšããªããšèããŠããŸãã
â .
, . , . Dart , , , , , Kotlin .
â Swift- , , force unwrap Dart.
void main() {
String? t;
print(t!.length);
}
( late â!â) .
late , - Dart. ârequiredâ . â@requiredâ, .
class Temp {
String str;
Temp({required this.str});
//
Temp.alt({strAtr}) : this.str = strAtr;
}
DartããŒã ã¯ãæè¡çãªãã¬ãã¥ãŒã«ãã«ã®å®å šæ§ãããããããã«1幎以äžåãçµãã§ããŸãããããã¯ã2çªç®ã®ããŒãžã§ã³ã®ãªãªãŒã¹ä»¥æ¥æå€§ã®èšèªå€æŽã§ãããã ããããã¯äžäœäºææ§ãæãªãããšã®ãªã倿Žã§ããæ¢åã®ã³ãŒãã¯nullã®å®å šæ§ã§ã³ãŒããåŒã³åºãããšãã§ãããã®éãå¯èœã§ããå®å šã«ãªãªãŒã¹ããåŸã§ããnullã»ãŒããã£ã¯ãæºåãã§ãããšãã«äœ¿çšã§ãã远å ã®ãªãã·ã§ã³ã«ãªããŸããæ¢åã®ã³ãŒãã¯å€æŽãããã«åŒãç¶ãæ©èœããŸãã
ã³ã¢Dartã©ã€ãã©ãªã¯ãnullã»ãŒããã£ã§æè¿æŽæ°ãããŸãããäžäœäºææ§ã®å®äŸãšããŠãæ¢åã®ã³ã¢ã©ã€ãã©ãªã®çœ®ãæãã¯ããã¹ãã1å倱æããããšãªããDartããã³Flutterãã¹ãç°å¢ã§å®è¡ãããŠãããã¹ãã¢ããªã±ãŒã·ã§ã³ã§ãšã©ãŒãçºçããããšããããŸããã§ããã Googleã®å éšã¯ã©ã€ã¢ã³ãã®å€ãã®ã³ã¢ã©ã€ãã©ãªã®æŽæ°ã§ãããåé¡ãªãå®è¡ãããŸããããªãªãŒã¹åŸã«nullã»ãŒããã£ã䜿çšããããã«ããã¹ãŠã®ããã±ãŒãžãšã¢ããªã±ãŒã·ã§ã³ãåèšèšããäºå®ã§ããåãããã«ããŠãã ãããããããããªãã¯èªåã®ããŒã¹ã§ããããããšã«ãã¢ããªããšã«ãããè¡ãããšãã§ããŸãã
ãããã®èšèã¯ãSwiftéçºè ãç¹ã«ç¬¬3ããŒãžã§ã³ã«ã¯åœãŠã¯ãŸããŸã...
ããããããã§ããã¹ãŠãããã»ã©ãã©è²ã§ã¯ãããŸããããéçºè èªèº«ã¯ã1ã€ã®ãããžã§ã¯ãã§nullå®å šã³ãŒããšãå€ããã³ãŒããçµã¿åããããšå¥å šæ§ãä¿èšŒã§ããªããšèšããŸãã¿ã€ãã·ã¹ãã ã
ãããªãè¡åèšç»
ãã«ã»ãŒããã£ã¯ã次ã®3ã€ã®ãã§ãŒãºã§æ®µéçã«å±éããäºå®ã§ãã
- ãã¯ãã«ã«ãã¬ãã¥ãŒãå ã®èšäºãå ¬éããããšãïŒ2020幎6æ10æ¥ïŒã«ãªãªãŒã¹ãããdev-branchã§å ¥æã§ããŸãããä»ããéå§ãã®ã»ã¯ã·ã§ã³ã«æ³šæãã䟡å€ããããŸãããŸã éåžžã«äžå®å®ã§ã倿Žãããå¯èœæ§ãããããã補åã³ãŒãã§ã®äœ¿çšã¯ãŸã ãå§ãããŸãããããããç§ãã¡ã¯ããªããã話ãèããŠãç§ãã¡ã«ãã£ãŒãããã¯ãäžãããã§ãïŒ
- ããŒã¿çããã«ã»ãŒããã£ã¯ããŒãããŒã¿ãã©ã³ãã§å©çšå¯èœã«ãªããå®éšãã©ã°ã®åŸãã«é ããããšã¯ãªããªããŸããå®è£ ã¯ãäºæ³ãããæçµããŒãžã§ã³ã«è¿ããªããŸããããã±ãŒãžãšãã©ã°ã€ã³ã®pub.devãžã®ç§»è¡ãéå§ããããšã¯å¯èœã§ããããã®å€æŽãå®å®ãããªãªãŒã¹ãšããŠå ¬éããããšã¯ãŸã ãå§ãããŸããã
- å®å®çããã«ã»ãŒããã£ã¯èª°ã§ãå©çšã§ããŸããæŽæ°ãããããã±ãŒãžãšãã©ã°ã€ã³ãå®å®çãªãªãŒã¹ãšããŠå ¬éããããã«æ±ããããŸãããã®æ®µéã§ã¢ããªã±ãŒã·ã§ã³ãç§»è¡ããããšã䟡å€ããããŸãã
ãã¹ãŠãèšç»éãã«é²ãã ãã幎æ«ãŸã§ã«å®å šæ§ããŒãã®å®å®çã®ããŒãããªãªãŒã¹ããäºå®ã§ããææããã«ã»ãŒããã£ãžã®ç§»è¡ã«åœ¹ç«ã€ããŒã«ã远å ããŸãããã®äžã§ïŒ
- æ¢åã®ããã±ãŒãžãšã¢ããªã±ãŒã·ã§ã³ãæŽæ°ããå€ãã®ã¹ããããèªååããã®ã«åœ¹ç«ã€ç§»è¡ããŒã«ã
- pub.dev, null safety;
- 'pub outdated' , null safety.
仿¥ãã«ã»ãŒããã£ã詊ãæãéãæ¹æ³ã¯ãnullsafety.dartpad.devã䜿çšããããšã§ããããã¯ãã«ã»ãŒããã£ãæå¹ã«ãªã£ãŠããããŒãžã§ã³ã®DartPadã§ãã Learn with SnippetsããããããŠã³ãªã¹ããéããŠãæ°ããæ§æãšnullã»ãŒããã£ã®åºæ¬ã«é¢ãããã¥ãŒããªã¢ã«ã·ãªãŒãºãèŠã€ããŠãã ããã
å°ããªã³ã³ãœãŒã«ã¢ããªã±ãŒã·ã§ã³ã§nullã®å®å šæ§ã詊ãããšãã§ããŸãïŒFlutterã®ãããªå€§ããªãã¬ãŒã ã¯ãŒã¯ã¯ãŸã æŽæ°ãããŠããŸããïŒããŸããdevãã©ã³ãããDart SDKãããŠã³ããŒãããå¿ èŠããããŸããæ¬¡ã«ããã®ãµã³ãã«ã³ã³ãœãŒã«ã¢ããªã±ãŒã·ã§ã³ãããŠã³ããŒãã§ããŸãã READMEãã¡ã€ã«ã«ã¯ãå®éšçãªnullå®å šæ©èœãæå¹ã«ããŠã¢ããªã±ãŒã·ã§ã³ãå®è¡ããããã®æé ãå«ãŸããŠããŸããäŸã®ä»ã®ãã¡ã€ã«ã¯ãVSCodeããã³AndroidStudioã§ã®ãããã°ãå¯èœã«ããå®è¡æ§æãæäŸããŸãã
ããã¥ã¡ã³ããèªãããšãã§ããŸãïŒä»åŸããã«è¡šç€ºãããŸãïŒã
- ãã«å®å šã¬ã€ã;
- å®å šæ§ããã«ã®ã³ã¢ã©ã€ãã©ãªã®APIãªãã¡ã¬ã³ã¹ã
UPDïŒã³ã¡ã³ãã§ãç§ã¯ãã®ãªã³ã¯ãææ¡ããŸããnullã®å®å šæ§ãçè§£ãã
Dartã§ãã«ã»ãŒããã£ãå®è£ ã§ããããšãéåžžã«å¬ããæããŸãã空ã®ãªã³ã¯ã®ä¿¡é Œæ§ãšå®å šæ§ã®é«ãåŠçã¯ãæãä¿¡é Œæ§ãé«ãçç£æ§ã®é«ãã³ãŒããäœæããã®ã«åœ¹ç«ã€Dartã®ç¹åŸŽã«ãªããŸãããã«ã»ãŒããã£ã®çŸåšã®ããŒãžã§ã³ã詊ããŠããã°ãã©ãã«ãŒã«ãã£ãŒãããã¯ãæ®ããŠãã ãããçŽ æµãªã³ãŒããïŒ
æåŸãŸã§èªãã§ãããŠããããšãã翻蚳ã¯å°ãé ããŸããããã³ã¡ã³ããè³æã«åœ¹ç«ã¡ã1察1ã®ç¿»èš³ã«ãªã£ãŠããªãããšãé¡ã£ãŠããŸãããã®æ©èœã¯ãFlutterãšã³ã·ã¹ãã å šäœã«ãšã£ãŠéåžžã«äŸ¿å©ãªäžæ©ã§ãããšä»ãå ããããšæããŸãããã§ã«ã©ã€ãã¢ããªã§äœ¿çšã§ããã®ã楜ãã¿ã«ããŠããŸãããããŸã§ã®éã圌ããå€åœèªã§èšãããã«ããæ¥œãã¿ã«ïŒ