可空表达式不能用作条件

Posted

技术标签:

【中文标题】可空表达式不能用作条件【英文标题】:A nullable expression can't be used as a condition 【发布时间】:2021-08-16 18:40:39 【问题描述】:

我对“可空表达式”有疑问。问题出在这两行:left: isSideBarOpenedAsync.data ? 0 : 0,right: isSideBarOpenedAsync.data ? 0 : screenWidth - 35, 我正在尝试用动画打开侧边栏菜单。一些想法来解决这个问题?泰。

这是错误:错误:'bool?' 类型的值不能分配给“bool”类型的变量,因为“bool?”可以为空,而 'bool' 不是。

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:solaris/constants.dart';
import 'package:rxdart/rxdart.dart';

class SideBar extends StatefulWidget 

  @override
  _SideBarState createState() => _SideBarState();


class _SideBarState extends State<SideBar> with SingleTickerProviderStateMixin<SideBar>
  late AnimationController _animationController;
  late StreamController<bool> isSidebarOpenedStreamController;
  late Stream<bool> isSideBarOpenedStream;
  late StreamSink<bool> isSideBarOpenedSink;
  final _animationDuration = const Duration(milliseconds: 500);

  @override
  void initState()
    super.initState();
    _animationController = AnimationController(vsync: this, duration: _animationDuration);
    isSidebarOpenedStreamController = PublishSubject<bool>();
    isSideBarOpenedStream = isSidebarOpenedStreamController.stream;
    isSideBarOpenedSink = isSidebarOpenedStreamController.sink;
  
  @override
  void dispose()
  _animationController.dispose();
  isSidebarOpenedStreamController.close();
  isSideBarOpenedSink.close();
  super.dispose();
  

  void onIconPressed()
    final animationStatus = _animationController.status;
    final isAnimationCompleted = animationStatus == AnimationStatus.completed;

    if(isAnimationCompleted)
      isSideBarOpenedSink.add(false);
      _animationController.reverse();
    else
      isSideBarOpenedSink.add(true);
      _animationController.forward();
    
  

  @override
  Widget build(BuildContext context) 
    final screenWidth = MediaQuery.of(context).size.width;

    return StreamBuilder<bool>(
      initialData: false,
      stream: isSideBarOpenedStream,
      builder: (context, isSideBarOpenedAsync)
        return AnimatedPositioned(
          duration: _animationDuration,
          top: 0,
          bottom: 0,
          left: isSideBarOpenedAsync.data ? 0 : 0,
          right: isSideBarOpenedAsync.data ? 0 : screenWidth - 35,
          child: Row(
            children: <Widget>[
              Expanded(
                child: Container(
                  color: red,
                ),
              ),
              Align(
                alignment: Alignment(0,-0.9),
                child: GestureDetector(
                  onTap: ()
                    onIconPressed();
                  ,
                  child: Container(
                    width: 35,
                    height: 110,
                    color: blue,
                    alignment: Alignment.centerLeft,
                    child: AnimatedIcon(
                      progress: _animationController.view,
                      icon: AnimatedIcons.menu_close,
                      color: white,
                      size: 25,
                    ),
                  ),
                ),
              ),
            ],
          ),
        );
      ,
    );
  


【问题讨论】:

【参考方案1】:

如果您知道isSideBarOpenedAsync.data 将始终有数据,您可以使用! 强制该值不为空。

例如: isSideBarOpenedAsync.data!。这会将值从 bool? 更改为 bool。您的三元表达式将使用此逻辑。

注意:如果isSideBarOpenedAsync.data 实际上是空的并且你有!,那么你会得到一个错误提示bool cannot be type null

如果你不希望这种行为,你也可以提供一个默认值。

例如:

(isSideBarOpenedAsync.data ?? false)

在这种情况下,如果isSideBarOpenedAsync.data 有一个值,它将被引用。如果为空,则使用false

【讨论】:

好的,我尝试将 right: isSideBarOpenedAsync.data ? 0 : screenWidth - 35, 更改为 right: (isSideBarOpenedAsync.data ?? 0 : screenWidth - 35),,但现在它给了我这个新错误:错误:参数类型“对象”不能分配给参数类型“双?”它还期望找到')'。 它应该是(isSideBarOpenedAsync.data ?? false) ? 0 : screenWidth - 35 我希望我们有将 null 视为 false 的 javascript 方法,但您的澄清很有帮助... 好@mrgnhnt96 刚刚放!在这样的条件之后是SideBarOpenedAsync.data!一切正常!

以上是关于可空表达式不能用作条件的主要内容,如果未能解决你的问题,请参考以下文章

DateAdd 和日期字段不能用作查询的条件

PLS-00363:表达式“i”不能用作赋值目标

为啥表达式'I_VALUE'不能用作函数中的赋值目标

C# Access OleDb 条件表达式中的数据类型不匹配

三元运算

SQL 中的错误 - 当子查询跟随 =、!=、<、<=、>、>= 或当子查询用作表达式时,这是不允许的