26

Flutter フレームワークに基づく個人用パッケージをアップグレードしています。ここで、Flutter Text ウィジェットのソース コードに null チェックがあることに気付きました。

if (textSpan != null) {
  properties.add(textSpan!.toDiagnosticsNode(name: 'textSpan', style: DiagnosticsTreeStyle.transition));
}

ただし、textSpan!まだ!演算子を使用しています。演算子textSpanを使用せずに null 非許容型に昇格する必要はありませんか? !ただし、演​​算子を削除しようとすると、次のエラーが発生します。

An expression whose value can be 'null' must be null-checked before it can be dereferenced.
Try checking that the value isn't 'null' before dereferencing it.

自己完結型の例を次に示します。

class MyClass {
  String? _myString;
  
  String get myString {
    if (_myString == null) {
      return '';
    }
    
    return _myString; //   <-- error here
  }
}

コンパイル時エラーが発生します。

エラー: タイプ '文字列?' の値 戻り値の型が「String」であるため、関数「myString」から返すことができません。

または、取得しようとすると_mySting.length、次のエラーが表示されます。

レシーバーが「null」になる可能性があるため、プロパティ「長さ」に無条件にアクセスすることはできません。

_myStringnull チェックを行うと、null非許容型に昇格すると思いました。なぜそうしないのですか?

私の質問は GitHub で解決されたので、以下に回答を投稿します。

4

3 に答える 3

34

Dart エンジニアの Erik Ernstは GitHub で次のように述べています。

型の昇格は、ローカル変数にのみ適用されます。... インスタンス変数の昇格は健全ではありません。計算を実行し、呼び出されるたびに異なるオブジェクトを返すゲッターによってオーバーライドされる可能性があるためです。参照。dart-lang/language#1188は、型の昇格に似ているが動的チェックに基づくメカニズムについての議論と、関連する議論へのリンクがあります。

したがって、ローカルタイプのプロモーションは機能します:

  String myMethod(String? myString) {
    if (myString == null) {
      return '';
    }
    
    return myString;
  }

ただし、インスタンス変数は昇格しません。!そのためには、演算子を使用して、この場合インスタンス変数が null ではないことを確信していることを Dart に手動で伝える必要があります。

class MyClass {
  String? _myString;
  
  String myMethod() {
    if (_myString == null) {
      return '';
    }
    
    return _myString!;
  }
}
于 2020-11-27T10:17:16.953 に答える