题 在Ruby on Rails中对nil v。空v。空白的简要解释


我发现自己一再寻找明确的差异定义 nil?blank?,和 empty? 在Ruby on Rails中。这是我最接近的:

  • blank? 对象是false,空或空白字符串。例如, """ "nil[],和 {} 是空白的。

  • nil? 对象是NilClass的实例。

  • empty? 对象是特定于类的,并且定义因类而异。如果字符串没有字符,则该字符串为空;如果字符串不包含任何项目,则该字符串为空。

有什么遗漏,或者可以做出更严格的比较吗?


957
2018-05-19 22:51


起源


一个问题是一个空数组返回false present?。这是因为 blank? 对于空数组返回true。 - Kris
一件好事就是看到了 :nil? 定义于 ::Kernel 并且被覆盖了 ::NilClass,而 :empty? 在许多类上单独实现(原生于 ::String, ::Array, ::Hash,非原生地在其他类上 ::Set来自stdlib和 ::ActiveRecord::Relation 来自铁路)。所以 :nil? 可用于所有子类 ::Object 以及包含的每个类别 ::Kernel 本身,在哪里 :empty? 必须在您的课程中专门实施或包含。 - rewritten
如果你试图了解整体 nil 概念 从这里开始。 - totymedli


答案:


.nil? 可以在任何对象上使用,如果对象为零,则为true。

.empty? 可用于字符串,数组和散列,并在以下情况下返回true:

  • 字符串长度== 0
  • 数组长度== 0
  • 哈希长度== 0

运行 .empty? 在nil的东西上会抛出一个 NoMethodError

那就是 .blank? 进来。它是 由Rails实现 并将操作任何对象以及工作 .empty? 在字符串,数组和散列上。

nil.blank? == true
false.blank? == true
[].blank? == true
{}.blank? == true
"".blank? == true
5.blank? == false
0.blank? == false

.blank? 还对非空的字符串求值为true,但只包含空格:

"  ".blank? == true
"  ".empty? == false

Rails还提供  .present?,它返回否定 .blank?

数组问题: blank? 将返回 false 即便如此 分子 数组是空白的。要确定此情况下的空白,请使用 all? 同 blank?, 例如:

[ nil, '' ].blank? == false
[ nil, '' ].all? &:blank? == true 

1278
2018-05-20 16:14



正如问题中所提到的,一些非空字符串计为空白。 - Andrew Grimm
你可以用“礼物”来更新你的答案吗?方法? - shajin
也: false.blank? == true - Shannon
我提到 presence! - Marc-André Lafortune
作为汤姆在他的回答中提到的全空白阵列问题的补充,请注意这可能会导致安全问题,攻击者可以使用无准备的代码,只需检查,除非params.nil?或者除非是params.blank ?,并且是目前在Rails中进行大量讨论和工作的原因。浏览此处获取更多信息: github.com/rails/rails/issues/13420 - Houen


我用所有的情况制作了这个有用的表格:

enter image description here


581
2017-12-18 16:29



应该注意空白?和礼物?仅限Rails。它们在Ruby 2.0.0中返回Exception:NoMethodError。 - Lonny Eachus
考虑添加 any? 如果你更新了表格。 - Dennis


只需扩展朱利安的表格:

enter image description here

参考: 空?空?零?傻傻分不清楚


173
2017-11-12 00:20



@Sibevin Wang,我已经下载了这个表,并在我的一些答案中使用了它,为你添加了学分。希望你不介意:)感谢这个巨大的努力! - Lahiru
Enumerable#any? 是vanilla Ruby,它不应该列在“仅限rails”下 - daniero
@daniero感谢您的提醒,表格已更新。 - Sibevin Wang
数字类型也有 .zero? 和 .nonzero? - DaveMongoose
它不必与Rails绑在一起,例如 github.com/SamSaffron/fast_blank (require 'fast_blank'; "".blank?) - Dorian


小建议: !obj.blank? == obj.present?

在某些表达方式中,可以方便/容易


56
2017-07-13 11:33



是否有相当于!obj.nil的东西? - Kirk
present? 是active_support的一部分,请在此处查看要包含的内容: stackoverflow.com/a/4648704/1569 - Factor Mystic
@Kirk:!! obj相当于!obj.nil? - Mohamed Hafez
@MohamedHafez不,不是。 !!false - Ajedi32
唉,@ Ajedi32好抓!等同于那个例外。 - Mohamed Hafez


一个区别是 .nil? 和 .empty? 是由编程语言Ruby提供的方法,而 .blank? 是的东西 添加 通过Web开发框架Rails。


43
2018-05-19 23:42





一个特例是在尝试评估布尔值是否为零时:

false.present? == false
false.blank? == true
false.nil? == false

在这种情况下,建议是使用 .nil?


9
2017-11-14 13:56





关于这个的一点点说明 any? 推荐:他是对的 通常 相当于 !empty?。然而, any? 将返回 true 到一个只是空格的字符串(ala " ")。

当然,请参阅上面的1.9评论。


8
2017-07-13 19:25



在Rails中,任何只包含空格字符的字符串都是“空白”:“\ n \ r \ t”.blank? #=>是的 - Lonny Eachus


enter image description here

  • 一切都是 nil? 是 blank?
  • 一切都是 empty? 是 blank?
  • 没什么 empty? 是 nil?
  • 没什么 nil? 是 empty?

tl; dr - 仅使用 blank? & present? 除非你想区分 "" 和 " "


8
2018-01-15 18:17



哇!你得到我的+1 - Am33d


别忘了 any? 这通常是 !empty?。在Rails中,我通常会检查语句末尾是否存在某些内容 if something 要么 unless something 然后用 blank? 在需要的地方,因为它似乎无处不在。


7
2018-05-19 23:51



。任何?不适用于ruby 1.9中的字符串,如.any?需要枚举,而字符串#the本身在ruby 1.9中不起作用。 - Andrew Grimm
小心 any? 检查非空虚。如果你有一个假数值数组,它返回false。解决这个问题的方法是传递一个始终为真的块: [nil, false].any?{ true }但是 !empty? 更短,你不记得奇怪的行为。 - Kelvin