如何在Ruby中理解nil vs.empty vs.blank


1128

我发现自己反复寻找的差异明确的定义nil?blank?以及empty?在Ruby on Rails的。这是我最近来的:

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

  • nil? 对象是NilClass的实例。

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

是否缺少任何内容,或者可以进行更严格的比较?


26
一个陷阱是一个空数组,返回的值为false present?。这是因为blank?对于空数组返回true。
克里斯(Kris)2012年

4
一个好处就是看:nil?定义上::Kernel和覆盖上::NilClass,而:empty?分别实施了许多类(本机上::String::Array::Hash,和非原生的其他类,如::Set从STDLIB和::ActiveRecord::Relation从轨)。所以,:nil?在所有的子类可用::Object并且还每类包括::Kernel由本身,:empty?必须在你的类实现或包括具体。
2013年

如果您想了解整个nil概念,请从这里开始
totymedli

[1] pry(main)> [].blank? => true
迈克尔

Answers:


1436

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

.empty? 可用于字符串,数组和哈希,如果满足以下条件,则返回true:

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

.empty?在无零的东西上运行会抛出一个负数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?也将返回。要确定这种情况下的空白,请与配合使用,例如:falseall?blank?

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

27
如问题中所述,一些非空字符串算作空白。
安德鲁·格林

1
他们为什么不改写nil的.empty?他们是否可以添加.blank?
直到2011年

6
另外:false.blank? == true
Shannon

2
我会提到presence
马克-安德烈·Lafortune

2
作为汤姆在回答中提到的全空白数组陷阱的补充,请注意,这可能导致安全问题,攻击者可以使用未经准备的代码来检查是否需要params.nil?或除非params.blank ?,否则是Rails当前进行大量讨论和工作的原因。在这里看到更多的信息:github.com/rails/rails/issues/13420
Houen

674

在所有情况下,我都制作了这个有用的表:

在此处输入图片说明

blank?present?由Rails提供。


57
应该注意空白吗?现在?仅限Rails。他们在Ruby 2.0.0中返回Exception:NoMethodError。
Lonny Eachus 2014年

17
any?如果要更新表,请考虑添加。
丹尼斯

blank?并且present?不是“ 仅Rails ”,它们会自动包含在Rails中,但可以通过使用ActiveSupport的Core扩展轻松地包含在非Rails代码中。见stackoverflow.com/questions/4238867/...
铁皮人

215

只需扩展朱利安的表:

在此处输入图片说明

参考:空?空白?无?傻傻分不清楚


1
@Sibevin Wang,我已经下载了这张表,并在我的一些回答中使用了它,以向您添加功劳。希望您不会介意:)为这项伟大的努力而感到荣幸!
Lahiru '16

1
Enumerable#any?是香草红宝石,不应在“仅导轨”下列出
daniero

1
@daniero感谢您的提醒,表格已更新。
Sibevin Wang

数字类型也有.zero?.nonzero?
DaveMongoose



49

在此处输入图片说明

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

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


2
哇!您获得了我的+1
Am33d '18

16

一种特殊情况是当尝试评估布尔值是否为nil时:

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

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


14

关于any?建议,请注意一点:他是对的,它通常等效于!empty?。但是,any?将返回true仅包含空格的字符串(ala " ")。

当然,也请参见上面的1.9注释。


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

13

别忘了any?一般!empty?。在Rails我通常检查的东西存在于一个语句的结束if somethingunless something再使用blank?在需要的地方,因为它似乎无处不工作。


4
。任何?不能在ruby 1.9中使用字符串,如.any?需要枚举,并且string#each本身在ruby 1.9中不起作用。
Andrew Grimm,2009年

4
仔细any?检查非空性。如果您有一个伪造的值数组,它将返回false。解决该问题的方法是传递一个始终为true的block :,[nil, false].any?{ true }!empty?它更短,并且您不记得奇怪的行为了。
Kelvin

12

nil?是可以在所有对象上调用的标准Ruby方法,true如果对象为,则返回nil

b = nil
b.nil? # => true

empty?是一种标准的Ruby方法,可以在某些对象(例如字符串,数组和哈希)上调用,true如果这些对象不包含任何元素,则返回:

a = []
a.empty? # => true

b = ["2","4"]
b.empty? # => false

empty?不能在nil对象上调用。

blank?是可以在nil对象以及空对象上调用的Rails方法。


7

其他人都很好地解释了区别。

我想添加Ruby On Rails,最好使用obj.blank?obj.present?代替obj.nil?or obj.empty?

obj.blank?处理所有类型的nil''[]{},并返回true如果值不可用,并返回false,如果值可用在任何类型的对象。


5

exists?方法可用于检查数据库中是否存在数据。它返回布尔值truefalse


仅适用于模型类!
罗杰

4

滑轨4

@ corban-brook的“数组陷阱:空白?”的替代方法 用于检查数组是否仅包含空值并且可以视为空白?真正:

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

一个人也可以做:

[nil, '', "", " ",' '].reject(&:blank?).blank? == true

3

nil?可以在任何对象上使用。它确定对象是否具有任何值,包括“空白”值。

例如:

example = nil
example.nil?  # true

"".nil?  # false

nil?如果对象实际上等于“ nil”,则基本上只会返回true。

empty?仅在被视为集合的对象上调用。这包括字符串(字符集合),哈希(键/值对集合)和数组(任意对象的集合)之类的东西。empty?如果集合中没有任何项目,则返回true。

例如:

"".empty? # true
"hi".empty?   # false
{}.empty?  # true
{"" => ""}.empty?   # false
[].empty?   # true
[nil].empty?  # false

nil.empty?  # NoMethodError: undefined method `empty?' for nil:NilClass

注意,empty?不能在nil对象上调用它,因为nil对象不是集合,它将引发异常。

还要注意,即使集合中的项目为空,也不表示集合为空。

blank?基本的组合nil?empty?你认为是集合这是用于检查的对象是有用的,但也可能是零。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.