先取り 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_typeslint rule. - Add the experimental
omit_obvious_property_typeslint rule. - Remove the
package_api_docslint rule. - Remove the
unsafe_html lintrule.
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