ChatGPT解决这个技术问题 Extra ChatGPT

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

我发现自己反复寻找 Ruby on Rails 中 nil?blank?empty? 的区别的明确定义。这是我最接近的:

空白的?对象为假、空或空白字符串。例如,“”、“”、nil、[] 和 {} 为空白。

零?对象是 NilClass 的实例。

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

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

一个问题是一个空数组为 present? 返回 false。这是因为 blank? 为空数组返回 true。
一件好事是看到 :nil?::Kernel 上定义并在 ::NilClass 上被覆盖,而 :empty? 在许多类(本机在 ::String::Array::Hash 和非-natively 在其他类上,例如来自 stdlib 的 ::Set 和来自 rails 的 ::ActiveRecord::Relation)。因此,:nil? 可用于 ::Object 的所有子类,也可用于单独包含 ::Kernel 的每个类,其中 :empty? 必须在您的类中实现或专门包含。
如果您尝试理解整个 nil 概念 start here
[1] pry(main)> [].blank? => true

a
alhimik45

.nil? 可用于任何对象,如果对象为 nil,则为真。

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

字符串长度 == 0

数组长度 == 0

哈希长度 == 0

在 nil 上运行 .empty? 将抛出 NoMethodError

这就是 .blank? 的用武之地。它是 implemented by 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 also provides .present?,它返回 .blank? 的否定。

数组陷阱:即使数组的所有 元素 都是空白,blank? 也会返回 false。要在这种情况下确定空白,请将 all?blank? 一起使用,例如:

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

如问题中所述,一些非空字符串算作空白。
为什么他们没有覆盖 nil 的 .empty?如果他们可以添加.blank?
另外:false.blank? == true
我之前曾看到在非 Rails 上下文中错误地使用了 blank?。如果您真的需要它,您可以include itrequire 'active_support/core_ext/object/blank'
作为汤姆在他的回答中提到的全空白数组陷阱的补充,请注意,这可能会导致安全问题,攻击者可以使用未经准备的代码来简单地检查除非 params.nil?或者除非 params.blank?,并且是目前在 Rails 中进行大量讨论和工作的原因。有关详细信息,请参见此处:github.com/rails/rails/issues/13420
d
dimpiax

我用所有案例制作了这张有用的表格:

https://i.stack.imgur.com/oXuhJ.png

blank?present? 由 Rails 提供。


应该注意空白?和礼物?仅限 Rails。它们在 Ruby 2.0.0 中返回异常:NoMethodError。
如果您曾经更新表,请考虑添加 any?
blank?present? 不是“Rails-only”,它们由 Rails 自动包含,但可以通过使用 ActiveSupport 的核心扩展轻松包含在非 Rails 代码中。请参阅stackoverflow.com/questions/4238867/…
S
Sibevin Wang

只需扩展 Julian 的表:

https://i.stack.imgur.com/qbe46.png

参考:empty?blank?nil?傻傻分不清楚


@Sibevin Wang,我已经下载了这张表,并在我的一些答案中使用了它,为你添加了学分。希望你不会介意 :) 对这项巨大的努力表示敬意!
Enumerable#any? 是原版 Ruby,不应将其列在“仅 Rails”下
@daniero 感谢您的提醒,表格已更新。
数值类型也有 .zero?.nonzero?
A
Alexander Malfait

快速提示:!obj.blank? == obj.present?

在某些表情中可以很方便/更容易在眼睛上


有没有与 !obj.nil 等价的东西?
present? 是 active_support 的一部分,请在此处查看要包含的内容:stackoverflow.com/a/4648704/1569
@Kirk: !!obj 等同于 !obj.nil?
@MohamedHafez 不,不是。 !!false
啊,@Ajedi32 不错!与那一个例外等效。
s
steve

https://i.stack.imgur.com/BdN1t.png

一切都是零?是空白吗?

一切都是空的?是空白吗?

没有什么是空的?是零?

没有什么是零?是空的?

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


t
the Tin Man

一个区别是 .nil?.empty? 是编程语言 Ruby 提供的方法,而 .blank? 是 Web 开发框架 Rails 提供的 added


A
Alan H

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

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

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


d
davemyron

关于 any? 建议的一点说明:他说得对,它通常等同于 !empty?。但是,any? 会将 true 返回为仅包含空格的字符串(ala " ")。

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


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

不要忘记 any?,它通常是 !empty?。在 Rails 中,我通常使用 if somethingunless something 检查语句末尾是否存在某些内容,然后在需要时使用 blank?,因为它似乎在任何地方都有效。


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

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

b = nil
b.nil? # => true

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

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

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

无法对 nil 对象调用 empty?

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


t
the Tin Man

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

我想在 Ruby On Rails 中添加,最好使用 obj.blank?obj.present? 而不是 obj.nil?obj.empty?

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


n
ndnenkov

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


仅适用于模型类!
m
mahatmanich

导轨 4

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

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

也可以这样做:

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

v
vidur punj

虽然这个问题有n个答案,但我喜欢这里解释的方式,所以再发布一个答案:-)

查看下面的数据指标 - 它可以通过可用方法中使用的各种数据类型进行自我解释。

https://i.stack.imgur.com/g4SrL.png

参考:https://blog.appsignal.com/2018/09/11/differences-between-nil-empty-blank-and-present.html


t
the Tin Man

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

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

另请注意,即使集合中的项目为空,也不意味着集合为空。

blank? 基本上是 nil?empty? 的组合 它对于检查您认为是集合的对象很有用,但也可以是 nil。