【问题标题】:How do you represent infinity in a JSON API?如何在 JSON API 中表示无穷大?
【发布时间】:2016-04-30 19:18:56
【问题描述】:

在 JSON API 中表示无穷大的最佳方式是什么?例如本月免费阅读文章(这在某些订阅中是有限的,而在高级订阅中是无限的)。

对于这个用例返回null 还是扩展 JSON 并使用javascript 的Infinity 值是更好的主意?后者似乎更合适,但我从未见过执行此操作的 API 示例。

如果有人有任何代表无限的公共 Web API 示例,那也太酷了。

【问题讨论】:

  • 我刚刚检查了一下,null 不是一个好的实现,因为当你需要使用 null 表示你会被卡住时,null 已经有意义了。所以就像在这个答案中使用字符串然后在处理时转换就可以了。 stackoverflow.com/questions/16644597/…这个
  • null 确实听起来是个坏主意 - 在某些情况下,像 PHP 这样的松散类型语言会将 null 转换为 0
  • 你能谈谈你想代表无穷大的具体情况吗?
  • 用一个特殊的情况来表示无穷大并不是一个好主意,请参阅下面的答案。

标签: json api infinity


【解决方案1】:

我会包含一个“限制”字段,它仅在确实存在限制时才存在:

当用户还剩 40 个时:

{
    "yourdata":"",
    "limit": 40
}

当用户拥有无限访问权限时,将其删除,这意味着没有限制:

{
    "yourdata":""
}

【讨论】:

  • 这里有一个问题,如果“limit”缺失,我们不知道它是否真的是无限的,或者是否有一些程序错误导致它丢失
  • 好的,您可以使用 boolean: "isLimited":"true/false" 添加另一个字段来仔细检查。但是你真的应该尝试制作一个你可以信任的api。如果这个字段可能是错误的,我不会相信任何其他字段。
  • 这就是我们最终在 API FWIW 中所做的事情。我会等到赏金期结束后再接受答案。在我们的内部用例中,缺少密钥会触发合理的默认设置。然而,相信文档的完整性感觉真的很奇怪。例如,我想象旧版本的 API 返回丢失的密钥。但我同意应该在不同的地方进行检查。
【解决方案2】:

我的建议是对特定值使用数字,对理论值使用字符串。我认为这是最清楚的。

{
  "shoes": 89,
  "cars": "infinity",
  "myBankAccount": "negative-infinity"
}

但是,这似乎不是流行的选择。我见过-1nullundefined(没有属性)在许多情况下意味着无限。

在 VMware,我们使用 -1 来指定没有限制(内存、CPU、VM),我们在使用 null 时遇到了问题,因为 BlazeDS 将 null 转换为 0,而 0 是一个有效值。

【讨论】:

    【解决方案3】:

    数字 1e500 被解析为无穷大

    
    console.log(1e500); // Gives Infinity
    
    Or
    
    JSON.parse('{"number": 1e500}'); // Gives {number: Infinity}
    
    

    【讨论】:

    • 哇,真不错!似乎实际上是从 1e309 开始的……
    • JSON.stringify(1e500) 给出 'null' 所以它不起作用。
    【解决方案4】:

    或许将无限订阅表示为完全不同的订阅类型会更好,因此您甚至不存在如何表示无限的问题。将来您可能希望尝试基于时间而不是数量的订阅,例如一个月内无限制访问,然后您必须处理到期日期。

    也就是说,一个有限但足够大的数字,例如 1e100 不是吗?如果你算一下,在浮点运算的有限精度中,1e100 - 1 = 1e100。

    【讨论】:

    • 我认为足够大的数字的问题是您必须在前端有特殊的规则才能在向用户显示之前对其进行处理。我猜是这样的:如果 free_to_read
    • FWIW 我想从前端隐藏订阅的概念,以便能够从后端更改它们。您的回答意味着前端需要根据订阅自行决定用户每月可以访问多少篇文章。
    • 无论如何你都必须处理这个问题。我不会告诉用户“您还有 Infinity 文章要阅读”
    • 是的,对不起。我的观点是,我必须在前端硬编码另一个数字,与我从后端得到的数字不同。感觉不太理想,必须记录前端需要寻找足够大的数字(多大?这个数字在 API 的后续版本中会改变吗?)并检查 一个较小的数字。
    • 无论您使用 Infinity、null、-1 还是任何其他特殊值,都会遇到同样的问题。这就是为什么我的第一个建议是对不同类型的订阅有不同的表示。
    【解决方案5】:

    您不能扩展 JSON。好吧,你可以扩展它,但它不再是 JSON。无法在 JSON 中表示 Infinity 或 NaN。数字有非常严格的语法,Infinity 或 NaN 不是其中的一部分。

    您可以存储一个非常大的值(1e300),您可以使用字符串“Inf”或“NaN”并确保处理它的每个人都正确处理它,或者可以使用 { "value": "Inf" } 然后你可以很确定每个人要么正确处理它,要么崩溃。

    【讨论】:

    • 改变合法值的语义从来都不是一个好主意,也不是保证混乱的秘诀。
    【解决方案6】:

    我会推荐使用 JavaScript 的 Infinity 值,因为它是一致的。

    例如:

    var x = 1;
    var y = 0;
    
    var z = x / y;
    
    console.log(z);
    
    // results in `Infinity`
    

    我想说null 也是另一种选择,但这可能会被误认为是没有价值,因为Infinity 实际上是一个无限可能的值。

    绝对不要使用NaN。这是一头怪异的野兽,ES为此异常道歉。

    以此为例:

    var x = NaN;
    
    if (x === x) {
        console.log('Good');
    } else {
        console.log('What?');
    }
    

    上述答案的结果是“什么?”这告诉我们 NaN 实际上是某种不是数字的值。

    另外,它的typeofnumber。您可以判断它是正无穷大还是负无穷大。如果您使用数字,请使用Infinity。它始终等于Infinity,将是最佳解决方案。

    var x = Math.log(0);
    
    console.log(x);
    console.log(typeof(x));
    
    if (x === x) {
        console.log('yes');
    }
    

    更新

    来自HERE - 你可以使用:

    { a: { is_infinity: true, value: null }, b: { is_infinity: false, value: 10 } }

    【讨论】:

    • 这些在 JSON 中无效,仅在 JavaScript 中有效
    • >由于 ECMA262 中 stringify() 函数的设计流程确实提到了三个特殊的 IEEE 值,因此可以怀疑其意图实际上是支持 IEEE754 浮点数。
    • NaN 和 Inf 不是 JS 特定的。它们是 IEEE 标准
    • 那个答案说 JSON 不支持无穷大??仅仅因为 IEEE 定义了它,并不意味着 JSON 使用它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-28
    • 1970-01-01
    • 2011-12-17
    • 2011-08-12
    相关资源
    最近更新 更多