断言在 dart 中做什么?

问题描述 投票:0回答:7

我很好奇在Dart编程中使用assert的目的。尽管我自己研究过,但我还不能完全理解它。如果有人能够解释 Dart 中断言的使用,那将会非常有帮助。

flutter dart
7个回答
121
投票

assert
的主要目的是在调试/开发期间测试条件。

让我们考虑一下这个例子:

class Product {
  Product({
    required this.id,
    required this.name,
    required this.price,
    this.size,
    this.image,
    this.weight,
  })  : assert(id > 0),
        assert(name.isNotEmpty),
        assert(price > 0.0);

  final int id;
  final String name;
  final double price;
  final String? size;
  final String? image;
  final int? weight;
}

我们有一个

Product
类,并且
id
name
price
等字段是强制性的,但正如您所猜测的,其他字段可以通过通用值来处理。通过断言必填字段,您将在调试/开发期间测试此数据类。请记住,在发布/生产模式下所有断言都将被忽略;

来自 dart.dev#assert

在生产代码中,断言将被忽略,并且断言的参数不会被评估。

与编写测试相比,尽管它们不是同一件事,但断言可以非常方便,只需付出最少的努力,因此请慷慨地编写断言,特别是如果您不编写测试,它总是会奖励您。

由于像

kDebugMode
kReleaseMode
这样的常量是
package:flutter/foundation.dart
的一部分,另一个用例是
debugMode
应用程序中的
Non-Flutter
特定代码。我们来看看这段代码:

bool get isDebugMode {
  bool value = false;
  assert(() {
    value = true;
    //you can execute debug-specific codes here
    return true;
  }());
  return value;
}

乍一看,它可能看起来很混乱,这是一个棘手但简单的代码。匿名闭包总是返回 true,因此在任何情况下我们都不会抛出任何异常。由于编译器在发布模式下消除了断言语句,因此该闭包仅在调试模式下运行并改变

value
变量。

调试时,您还可以像此示例一样扩展用例,来自

Flutter
源代码:

void addAll(Iterable<E> iterable) {
  int i = this.length;
  for (E element in iterable) {
    assert(this.length == i || (throw ConcurrentModificationError(this)));
    add(element);
    i++;
  }
}

同样,异常仅在调试模式下抛出,您现在可以更轻松地区分违规。

可空示例

For the versions of Dart before 2.12
,你的典型例子应该是这样的:

import 'package:meta/meta.dart';

class Product {
  final int id;
  final String name;
  final int price;
  final String size;
  final String image;
  final int weight;

  const Product({
    @required this.id,
    @required this.name,
    @required this.price,
    this.size,
    this.image,
    this.weight,
  }) : assert(id != null && name != null && price != null);
}


21
投票

这里

在开发过程中,使用断言语句——assert(condition, optionalMessage); — 如果布尔条件为假,则中断正常执行。

假设您要打开一个必须以

"https"
开头的 URL。您将如何确认这一点?这是一个例子。

示例:

void openUrl({String url}) {
  assert(url.startsWith('https'), 'The url should start with https');
  
  // We can proceed as we 'https' in the url.
}

7
投票

assert 类似于Error,因为它用于报告不应该发生的不良状态。不同之处在于 asserts 仅在调试模式下检查。它们在生产模式中被完全忽略

例如:

OverlayEntry({
  @required this.builder,
  bool opaque = false,
  bool maintainState = false,
}) : assert(builder != null),
      assert(opaque != null),
      assert(maintainState != null),
      _opaque = opaque,
      _maintainState = maintainState;

1
投票

https://dart.dev/guides/language/language-tour#assert 在开发过程中,使用断言语句——assert(condition, optionalMessage); — 如果布尔条件为假,则中断正常执行。您可以在本教程中找到断言语句的示例。这里还有一些:

// 确保变量具有非空值。 断言(文本!= null);

// 确保该值小于 100。 断言(数字 < 100);

// 确保这是一个 https URL。 断言(urlString.startsWith('https')); 要将消息附加到断言,请添加一个字符串作为断言的第二个参数(可以选择使用尾随逗号):

assert(urlString.startsWith('https'), 'URL ($urlString) 应以“https”开头。'); 断言的第一个参数可以是解析为布尔值的任何表达式。如果表达式的值为 true,则断言成功并继续执行。如果为 false,则断言失败并抛出异常(AssertionError)。

断言到底什么时候起作用?这取决于您使用的工具和框架:

Flutter 在调试模式下启用断言。 仅限开发的工具(例如 dartdevc)通常默认启用断言。 某些工具(例如 dart run 和 dart2js)通过命令行标志支持断言:--enable-asserts。 在生产代码中,断言将被忽略,并且断言的参数不会被评估。


1
投票

作为一名程序员,编写无错误的代码是非常有必要的,而查找错误是非常困难且耗时的。 Dart 提供了

assert
形式的解决方案来验证您的代码并确保代码能够正常工作而不会出现任何错误。
assert
在调试中很有用,它在语法中使用布尔条件。如果断言语句中的布尔表达式为 true,则代码继续执行,但如果返回 false,则代码以断言错误结束。


0
投票

assert 语句是调试代码的有用工具,它使用布尔条件进行测试。在一个大程序中,编写无错误的代码是非常必要的,并且发现错误是非常困难的。 Dart 提供了断言语句来检查错误。

Syntax: assert(condition);

确保 str 具有非空值。

assert(str != null);

确保数量小于 50。

assert(num < 50);
`


-1
投票

assert 类似于Error,因为它用于报告不应该发生的不良状态。不同之处在于 asserts 仅在调试模式下检查。它们在生产模式中被完全忽略。

© www.soinside.com 2019 - 2024. All rights reserved.