未来的本地变量不保存值并返回null。

huangapple go评论65阅读模式
英文:

future local variable doesn't save the value and returns null

问题

我已经在函数(Future)内为本地变量分配了一个值,但结果始终返回null值。我的代码中是否有任何错误?

enum StatusUser { telahMasuk, belumMasuk, berhasilMasuk, gagalMasuk }

class MyClass {
  Future<StatusUser> muatSeting(String? key) async {
    StatusUser? sp;

    final data = await getUserData();
    try {
      if (data != null) {
        final dataToken = jsonDecode(
            APIUser().decodeJWT(data['token'].toString().split('.')[1]));
        if (new DateTime.now().millisecondsSinceEpoch -
                dataToken['tgl_verify'] <
            864000) {
          sp = StatusUser.telahMasuk;
        }
      } else {
        sp = StatusUser.belumMasuk;
      }
    } catch (e) {
      print(e);
    }
    return sp!;
  }
}

在调试时,它显示_CastError (Null check operator used on a null value)。而在以前的Flutter版本中,它可以工作。我希望这个future从变量sp返回一个枚举值。

❯ flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[] Flutter (Channel stable, 3.7.7, on Ubuntu 22.04.2 LTS 5.19.0-38-generic, locale id_ID.UTF-8)
Checking Android licenses is taking an unexpectedly long time...[] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
[] Chrome - develop for the web
[] Linux toolchain - develop for Linux desktop
[!] Android Studio (not installed)
[] VS Code (version 1.76.2)
[] Connected device (3 available)
[] HTTP Host Availability
英文:

I've assigned a value for a local variable inside a function (Future), but the result always gives a null value. Is there any wrong code in my code?

enum StatusUser { telahMasuk, belumMasuk, berhasilMasuk, gagalMasuk }

class MyClass {
  Future&lt;StatusUser&gt; muatSeting(String? key) async {
    StatusUser? sp;

    final data = await getUserData();
    try {
      if (data != null) {
        final dataToken = jsonDecode(
            APIUser().decodeJWT(data[&#39;token&#39;].toString().split(&#39;.&#39;)[1]));
        if (new DateTime.now().millisecondsSinceEpoch -
                dataToken[&#39;tgl_verify&#39;] &lt;
            864000) {
          sp = StatusUser.telahMasuk;
        }
      } else {
        sp = StatusUser.belumMasuk;
      }
    } catch (e) {
      print(e);
    }
    return sp!;
  }
}

When I debugging, its shows _CastError (Null check operator used on a null value). Whereas at previous version of Flutter, it works. I want that this future returning an enum value from variable sp.

❯ flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[] Flutter (Channel stable, 3.7.7, on Ubuntu 22.04.2 LTS 5.19.0-38-generic, locale id_ID.UTF-8)
Checking Android licenses is taking an unexpectedly long time...[] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
[] Chrome - develop for the web
[] Linux toolchain - develop for Linux desktop
[!] Android Studio (not installed)
[] VS Code (version 1.76.2)
[] Connected device (3 available)
[] HTTP Host Availability

答案1

得分: 1

The null check operator is failing here because sp is null.
这里空值检查运算符失败,因为sp是空的。

Looking from the if statement, I think this condition fails (new DateTime.now().millisecondsSinceEpoch - dataToken[&#39;tgl_verify&#39;] &lt; 864000) and therefore sp is never set.
从if语句的角度看,我认为这个条件失败了(new DateTime.now().millisecondsSinceEpoch - dataToken[&#39;tgl_verify&#39;] &lt; 864000),因此sp从未被设置。

英文:

The null check operator is failing here because sp is null.

return sp!;

Looking from the if statement, I think this condition fails (new DateTime.now().millisecondsSinceEpoch - dataToken[&#39;tgl_verify&#39;] &lt; 864000) and therefore sp is never set.

if (data != null) {
    final dataToken = jsonDecode(
        APIUser().decodeJWT(data[&#39;token&#39;].toString().split(&#39;.&#39;)[1]));
    if (new DateTime.now().millisecondsSinceEpoch -
            dataToken[&#39;tgl_verify&#39;] &lt;
        864000) { // this if statement never runs so sp is null.
      sp = StatusUser.telahMasuk;
    }
  }

答案2

得分: 1

如果您希望默认情况下返回 StatusUser.belumMasuk,那么您可以选择初始化 sp 以将其用作默认值:

Future<StatusUser> muatSeting(String? key) async {
  StatusUser sp = StatusUser.belumMasuk;

  final data = await getUserData();
  try {
    if (data != null) {
      final dataToken = jsonDecode(
          APIUser().decodeJWT(data['token'].toString().split('.')[1]));
      if (DateTime.now().millisecondsSinceEpoch - dataToken['tgl_verify'] <
          864000) {
        sp = StatusUser.telahMasuk;
      }
    }
  } catch (e) {
    print(e);
  }
  return sp;
}

或者使用 ?? 运算符:

Future<StatusUser> muatSeting(String? key) async {
  StatusUser? sp;

  final data = await getUserData();
  try {
    if (data != null) {
      final dataToken = jsonDecode(
          APIUser().decodeJWT(data['token'].toString().split('.')[1]));
      if (DateTime.now().millisecondsSinceEpoch - dataToken['tgl_verify'] <
          864000) {
        sp = StatusUser.telahMasuk;
      }
    }
  } catch (e) {
    print(e);
  }
  return sp ?? StatusUser.belumMasuk;
}

这两种情况都可以让您删除 else 块,而且还能处理在 try 块内抛出异常的情况。此外,您应该避免没有 on 子句的 catch 语句

在您的回答中,您提到:

我对 '为什么在没有 else 和 false 条件的嵌套 if 中不返回父 if 中设置的值感到困惑';

为什么要这样做呢?这不是 if-else 的工作方式。外部的 else 块仅对应外部的 if 条件。

想象一下:

if (condition1) {
  if (condition2) {
    doStuff();
  }

  doLotsOfOtherStuff();
} else {
  handleCondition1Failed();
}

如果 condition2false,您是否希望跳过 doLotsOfOtherStuff()?但如果是这样,那么 doLotsOfOtherStuff() 应该被移动到 if (condition2) 块内。您是否希望同时执行 doLotsOfOtherStuff()handleCondition1Failed()?其中任何选择都会令大多数人感到难以理解。

如果希望在 condition1condition2 失败时执行 else 块,那么应该编写如下方式:

var succeeded = false;

if (condition1) {
  if (condition2) {
    doStuff();
    succeeded = true;
  }

  doLotsOfOtherStuff();
}

if (!succeeded) {
  handleFailure();
}
英文:

If you want StatusUser.belumMasuk to be returned by default, then you either should initialize sp to use that as its default value:

Future&lt;StatusUser&gt; muatSeting(String? key) async {
  StatusUser sp = StatusUser.belumMasuk;

  final data = await getUserData();
  try {
    if (data != null) {
      final dataToken = jsonDecode(
          APIUser().decodeJWT(data[&#39;token&#39;].toString().split(&#39;.&#39;)[1]));
      if (DateTime.now().millisecondsSinceEpoch - dataToken[&#39;tgl_verify&#39;] &lt;
          864000) {
        sp = StatusUser.telahMasuk;
      }
    }
  } catch (e) {
    print(e);
  }
  return sp;
}

or use the ?? operator:

Future&lt;StatusUser&gt; muatSeting(String? key) async {
  StatusUser? sp;

  final data = await getUserData();
  try {
    if (data != null) {
      final dataToken = jsonDecode(
          APIUser().decodeJWT(data[&#39;token&#39;].toString().split(&#39;.&#39;)[1]));
      if (DateTime.now().millisecondsSinceEpoch - dataToken[&#39;tgl_verify&#39;] &lt;
          864000) {
        sp = StatusUser.telahMasuk;
      }
    }
  } catch (e) {
    print(e);
  }
  return sp ?? StatusUser.belumMasuk;
}

Both cases would allow you to remove the else blocks and additionally would handle the case where an exception is thrown within the try block. (Incidentally, you should avoid catches without on clauses.)

In your answer, you made a remark:

> I'm in confuse with 'why nested if (child) when without else and false condition dosen't returning value that was set on else from parent if'

Why would it? That's not how if-else works. The outer else block corresponds only to the outer if condition.

Imagine:

if (condition1) {
  if (condition2) {
    doStuff();
  }

  doLotsOfOtherStuff();
} else {
  handleCondition1Failed();
}

If condition2 is false, do you expect doLotsOfOtherStuff() to be skipped? But if so, then doLotsOfOtherStuff() should be moved to be within the if (condition2) block. Do you expect doLotsOfOtherStuff() and handleCondition1Failed() to both be executed? Either of those choices would be unintuitive and very hard to follow for most people.

If you want the else block to be executed if either condition1 or condition2 fails, then you should write it as:

var succeeded = false;

if (condition1) {
  if (condition2) {
    doStuff();
    succeeded = true;
  }

  doLotsOfOtherStuff();
}

if (!succeeded) {
  handleFailure();
}

答案3

得分: 0

I've solved it with adding else on nested if:

if (data != null) {
    final dataToken = jsonDecode(
        APIUser().decodeJWT(data['token'].toString().split('.')[1]));
    if (new DateTime.now().millisecondsSinceEpoch - dataToken['tgl_verify'] < 864000) {
        sp = StatusUser.telahMasuk;
    } else {
        sp = StatusUser.belumMasuk;
    }
} else {
    sp = StatusUser.belumMasuk;
}

I'm in confuse with 'why nested if (child) when without else and false condition doesn't return the value that was set on else from the parent if.

英文:

I've solved it with adding else on nested if

if (data != null) {
    final dataToken = jsonDecode(
        APIUser().decodeJWT(data[&#39;token&#39;].toString().split(&#39;.&#39;)[1]));
    if (new DateTime.now().millisecondsSinceEpoch -
            dataToken[&#39;tgl_verify&#39;] &lt; 864000) {
        sp = StatusUser.telahMasuk;
    } else {
        sp = StatusUser.belumMasuk;
    }
  } else {
    sp = StatusUser.belumMasuk;
  }

I'm in confuse with 'why nested if (child) when without else and false condition dosen't returning value that was set on else from parent if'

huangapple
  • 本文由 发表于 2023年4月4日 11:35:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/75925318.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定