这可能是一个更美观的问题,但我发现它真的很烦人,因为我总是最终得到一些丑陋的代码。可读性总是很重要,对吗?
我想检查散列中的散列中是否存在值。我所做的就是这个。
already_exists_data[:data][:user_id]
但是,如果:data为nil并且正在检查:如果already_exists_data为nil,数据可能会给我一个nullpointer,那么这可以得到一个nullpointer异常。所以我最终得到的是:
if already_exists_data && already_exists_data[:data] && already_exists_data[:data][:user_id]
# Do stuff
end
现在这是一些讨厌的代码。也许我应该将哈希修改为对象。但是我有时会一直碰到这个问题,并且想知道你们是如何对抗它的。
我目前正在使用Ruby进行编码,但我遇到了其他多种语言的问题。
答案 0 :(得分:2)
如果我让我的管家在维多利亚街34号的餐桌上拿起一盒巧克力,我就问他。我不想说:去寻找维多利亚街,如果你找到它,请找34号,如果你找到它......
我能做到这一点,因为他抓住了自己的错误:如果他找不到街道,他就会空手而归。
因此,您应该使用带有空异常处理程序的try
。在伪代码中:
尝试{巧克力=街道(“维多利亚”)(34)(“餐厅”)(“桌子”)}
在语言中(例如ruby
,有一些homespun syntactic sugar),其中块是你可能写的表达式:
如果尝试{already_exists_data(data)(user_id)}
do_stuff
语言本身也可以提供帮助:在perl
中,$streets{Victoria}[34]{dining_room}{table}
未定义,例如$streets
是。当然,在您发现地址错误之前,您的管家可能会空手而归。 try
阻止解决方案 - 以及您的if .. && ....
- 也有同样的缺点:只有当您真的不在乎维多利亚街是否有34号时才使用它们。
答案 1 :(得分:1)
与语言无关的解决方案:不使用空值。永远。在整个项目中实施此规则。如果你绝对必须,wrap them into Either
/Optional
which adds explicitness。某些语言(例如Scala)已经内置了Optional
的概念。
特定于Java的解决方案:如果必须使用空值,注释方法参数并使用@Nullable
和@Nonnull
返回值。如果从这样的方法获取值,体面的IDE(例如IntelliJ)能够分析您的代码并突出显示可能的null
解除引用。
答案 2 :(得分:1)
另一种可能性是使用函数调用包装散列访问,并在函数内执行“脏”工作。然后你的代码就像(伪代码语法):
accessHash(already_exists_data, data, userid)
注意:您可以根据传递给包装函数的参数数量来访问嵌套哈希,因此它适用于多种情况。