先取り Dart 3.7 の変更点
結構ありそうだったのでまとめます。
執筆当時の最新はまだ Dart 3.6 なので、是非皆さんも 3.7 アプデ時に「ついにこの機能来るのかぁ」とドヤ顔できるように頑張りましょう。
Wildcard
使用しないコールバックの引数などに 慣例的に 命名していた _
変数に、ワイルドカードとしてのちゃんとした機能を付与する。
👇 こういうやつ
showDailog(
builder: (_) => MyDialog(),
);
特に、Dart 3.0 で導入された Record
でもたまに使用するようになった。
final myRecord = (1, 'a', false));
final (_, str, __) = myRecord;
print(str);
付与される機能
-
_
変数の使用を禁止する
今までは、慣例的に_
をつけていただけなので、_
変数を使って print したりできましたが、それができないようになりました。慣例が、ちゃんとした機能になりました。👏(たまに print でログに出してたのができなくなりました)
-
_
変数の複数宣言を可能にする
今まで、使わない変数が複数ある場合は__
、___
と、アンスコを増やさないといけませんでしたが、全て_
で対応できるようになりました。// before PageRouteBuilder( pageBuilder: (_, __, ___) { return Container(); } )
// after PageRouteBuilder( pageBuilder: (_, _, _) { return Container(); } )
DartPad で試した結果
Analyzer
VScode, Android Studio とかの Quick Fix の補完機能が、結構充実するそうです。
Expanded/Flexible
の補完
今まで手入力していたExpanded/Flexible
が補完できるようになりました。
Before
After
さらにポイントとして、Expanded/Flexible
は Column
や Row
の children として使う前提のウィジェット(ParentDataWidget<FlexParentData>
)であるので、Column
や Row
の children 出なければ、サジェストされません(すごい)。
相対パス・絶対パスのサジェスト
Assists and quick fixes that add an import now consider the prefer_relative_imports and always_use_package_imports lint rules.
たとえば、相対パスのみで運用する警告を有効にした時に効力を発揮します。
linter:
rules:
prefer_relative_imports: true
import '../../service/shared_preferences/base_shared_preferences_service.dart';
import '../../service/shared_preferences/shared_preferences_key.dart';
import 'package:my_app/service/shared_preferences/shared_preferences.dart';
// Use relative imports for files in the 'lib' directory.
// Try converting the URI to a relative URI.dartprefer_relative_imports
Before
相対パスのみなのに、package:
import がサジェストされる。
After
相対パスのみサジェストされる。
await
で解決できるとこの補完
Add a fix that wraps an expression in await if the expression is currently not assignable, but awaiting it would make it assignable.
たとえば、以下のように String
がFuture<String>
を受け取るとき、もちろん型が違うのでエラーが発生します。
Future<String> futureString() {
return Future.value('xxx');
}
void main() async {
var str = '';
// A value of type 'Future<String>' can't be assigned to a variable of type 'String'.
str = futureString();
print(str);
}
Before
単に「型が違う」とだけ解釈される。
After
await
の解決策も提示して quick fix ができる。
たまに発生してたのでありがたい。
cascade_invocations
の quick fix
Add an additional fix to correct a cascade_invocations lint rule violation.
ref.invalidate(userProvider);
ref.invalidate(postProvider);
ref.invalidate(notificationProvider);
↓ quick fix
ref..invalidate(userProvider)
..invalidate(postProvider)
..invalidate(notificationProvider);
Before
2つを1つにすることはできていた。
なので、3つ以上の場合は1ずつつ行う必要があった。
After
3つ以上の場合も一気にできるようになった。
forEach を for-loop にするとき
prefer_final_in_for_each
と always_specify_types
を考慮してアシスト(Before みた方がわかりやすい)。
Before
「var
ではなく final
」「型の宣言」の警告が出るのがわかってるのに、その形になってしまう。
After
1発で、警告を考慮した変換をしてくれる。
else
内の if-else を、else if
に変換
Offer an assist to "inline" an else-block's inner if-statement with the else-block to read else if. (Thanks @FMorschel for the above enhancements!
例えば、こういう関数があったとする。
void wasmJudge() {
if (!kIsWeb) {
print('not Web');
} else {
if (kIsWasm) {
print('is Wasm');
}
}
}
この分岐は、else
のなかの if
を、else if
に変換しても、論理的には同じになる。
void wasmJudge() {
if (!kIsWeb) {
print('not Web');
} else if (kIsWasm) {
print('is Wasm');
}
}
After
これを quick fix で解決できる。
すごい。
else
のなかの分岐が複数あっても対応できる。
~/
演算子
🤔 Add a new fix that converts a ~/ operation into /, when the ~/ operation is not available.
~/
が使えない時、/
へ変換する quick fix が出るっぽい。
試しに、double
へ ~/
の結果を入れる(~/
の結果は int
なのでエラーになる)のやってみたけど、何も出ない。
これはなんだ。
その他、追加・削除ルール
- Add the experimental
specify_nonobvious_property_types
lint rule. - Add the experimental
omit_obvious_property_types
lint rule. - Remove the
package_api_docs
lint rule. - Remove the
unsafe_html lint
rule.
Dart Format
print_width
コード1行の文字数が、今まで80文字をオンオフにするしかなかったのですが、好みに合わせて行数が指定できるようになりました。
include: package:flutter_lints/flutter.yaml
formatter:
page_width: 123
一時的にフォーマットをオフにできるようになった
// dart format off
から // dart format on
までの範囲指定するっぽいです。
こーーれだいぶ嬉しいです。
main() {
this.isFormatted();
// dart format off
no + formatting
+
here;
// dart format on
formatting.isBackOnHere();
}
たとえば、同じような要素を並べる時に、一部項目だけ表示が違うと少し見通しが悪くなったりします。
final hours = duration.inHours;
final minutes = duration.inMinutes.remainder(60);
final seconds = duration.inSeconds.remainder(60);
final milliSeconds =
duration.inMilliseconds.remainder(1000);
ProviderScope(
overrides: [
sharedPreferencesProvider
.overrideWithValue(sharedPreferencesInfrastructure),
inAppPurchaseProvider.overrideWithValue(inAppPurchase),
googleAdmobProvider.overrideWithValue(googleAdmob),
],
);
``````dart
// dart format off
final hours = duration.inHours;
final minutes = duration.inMinutes.remainder(60);
final seconds = duration.inSeconds.remainder(60);
final milliSeconds = duration.inMilliseconds.remainder(1000);
// dart format on
フォーマッタのせいで逆に読みづらくなることはたまにあるので、うまく使っていきたいです。
ProviderScope(
overrides: [
// dart format off
sharedPreferencesProvider
.overrideWithValue(sharedPreferencesInfrastructure),
inAppPurchaseProvider.overrideWithValue(inAppPurchase),
googleAdmobProvider.overrideWithValue(googleAdmob),
// dart format on
],
);
Discussion