Dart 中的 double.infinity 和 double.maxFinite 有什么区别?

Jae*_*ung 6 dart flutter

Dart 中的 double.infinity 和 double.maxFinite 有什么区别?

在 Flutter 中,看起来两者都做同样的事情。我应该什么时候在 Flutter 中使用它们?

Abi*_*n47 5

从严格面向数据的角度来看,区别在于表示数据类型可以包含的double.maxFinite最大允许值,而表示无穷大。由于 Dart在所有平台上严格定义为 64 位浮点数,因此已知 的值为。(具体原因相当技术性,但 jpopesculian 的答案在某种程度上涉及到这一点,一般来说,对于简单的应用程序开发来说,通常不需要理解这些细节。)doubledouble.infinitydoubledouble.maxFinite1.7976931348623157e+308

\n

在 Flutter 中,大多数时候,这两个值之间没有巨大的实际差异。您会看到这些常量的地方通常是在调整小部件的大小方面,通常当您希望小部件尽可能大时,您可以传递double.infinity它的宽度和/或高度:

\n
SizedBox(\n  width: 500,\n  height: 500,\n  child: Container(\n    width: double.infinity,\n    height: double.infinity,\n  ),\n)\n
Run Code Online (Sandbox Code Playgroud)\n

在此示例中,子级Container被赋予无限的宽度和高度。Flutter 将通过使用其父级来确定其实际可用的空间并在必要时对其进行约束来计算其大小。在这种情况下,Container受到 的约束SizedBox,后者对 强制执行 500 像素 x 500 像素的硬限制Container- 无论请求多少空间Container,它都不能比这个更大。因此,替换double.infinitydouble.maxFinite不会改变任何东西,因为父级SizedBox仍然只会让它变得这么大。

\n

通常情况就是这样,因为 Flutter 中的大多数布局小部件都带有某种隐式约束,要么作为其功能的一部分,要么从其父级继承(最终,将类似于 或 a ,将MaterialAppScaffold子级限制为大小)屏幕)。因此,很多时候,孩子们试图比他们所能容纳的空间更大不会有太大的问题,因为 Flutter 的布局规则足够强大,可以防止他们占用比允许的更多的空间。

\n

不过,在某些情况下,无限约束可能会导致问题。就拿这个非常做作的例子来说:

\n
Column(\n  children: [\n    Container(\n      height: double.infinite,\n    ),\n  ],\n)\n
Run Code Online (Sandbox Code Playgroud)\n

在这里,我们有一个Column它的效果是为其子级创建一个无限大的垂直空间以供其存在。作为它的子级,它有一个Container要求无限高度的 a 。问题很清楚:Flutter 如何在具有无限约束的父 widget 中约束无限高的 widget?确实,尝试渲染这个小部件会产生以下错误:

\n
\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90 Exception caught by rendering library \xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90 \nThe following assertion was thrown during performLayout():\nBoxConstraints forces an infinite height.\n
Run Code Online (Sandbox Code Playgroud)\n

因此,如果问题是无限大小的小部件不能存在于无限受限的空间中,那么如果我们将double.infinity改为double.maxFiniteContainer?这将解决问题,因为Container不再是无限大小并且 Flutter 可以正常计算其约束:

\n
\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90 Exception caught by rendering library \xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90 \nThe following assertion was thrown during performLayout():\nBoxConstraints forces an infinite height.\n
Run Code Online (Sandbox Code Playgroud)\n

成功!无限高度约束误差消失了!

\n

...我们只是得到这个错误:

\n
\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90 Exception caught by rendering library \xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\nThe following assertion was thrown during layout:\nA RenderFlex overflowed by 1.7976931348623157e+308 pixels on the bottom.\n
Run Code Online (Sandbox Code Playgroud)\n

所以,是的,虽然现在已经正确计算了高度,但Column如果它的子级比可用空间高,就会抱怨,而且事实证明,大约一百百亿像素对于现代屏幕来说有点太高了。[需要引用]

\n

(对于那些好奇的人来说,这里的解决方案是将 包装Container在 中Expanded,这将占用 中的可见空间,Column并且将再次强制执行有限约束,限制Container占用比允许的更多的空间。[或者,你知道,你也不能首先创建这样一个尺寸过大的小部件。])

\n

简而言之,在您可能使用 Flutter 的地方,和double.infinity之间通常没有任何实际区别。但在这种情况下,你通常最终只是用一个问题换另一个问题。double.infinitydouble.maxFinite

\n

综上所述,Flutter 小部件库的大部分内容都是作为double.infinity潜在的有效输入编写的,因此在大多数情况下,您将获得明确定义的行为或详细的错误消息。然而,我希望对 的使用的double.maxFinite直接支持要少得多,因此虽然它在很多时候都可以工作,但在不工作的情况下,您可能无法获得关于到底出了什么问题的非常清晰的反馈。所以,一般来说,只要double.infinity在适当的地方使用,而在其他地方,坚持使用对我们凡人的头脑更有意义的数值。

\n