我正在开发一个从Objective C移植到Java的代码库。没有nullchecks的方法链接有几种用法
dog.collar().tag().name()
我正在寻找类似于safe-dereferencing operator的东西?在Groovy而不是nullcheck
dog.collar?.tag?.name
这导致Maybe monad拥有Nothing的概念而不是Null。但是当我访问值时仍然没有解决链接问题的Nothing的所有实现都会抛出异常。我做了Nothing返回一个模拟,它的行为类似于NullObject模式。但它解决了链式问题。
Nothing的实现有什么问题吗?
public class Nothing<T> implements Maybe<T> {
private Class<T> klass;
public Nothing(Class<T> klass) {
this.klass = klass;
}
@Override
public T value() {
return mock(klass, Mockito.RETURNS_DEEP_STUBS);
}
}
据我所知
答案 0 :(得分:7)
我不建议只检查空值。实际上,我建议甚至不要返回null,而是抛出异常。
在任何一种情况下,你都不会通过这种空对象方法更快地制作代码,而且我认为你最终会因为想要复制不同编程语言的特性而混淆某人。我认为你应该适应你正在使用的语言。
答案 1 :(得分:4)
我也喜欢这个运算符,但它不适用于Java - 而且它是一个关于草率代码的止损补丁:如果dog.collar没有标记,它应该分支不同,如果是标签没有名称 - 它可能是一个错误,应该抛出异常。
当你继承你没有写的代码时,并不能解决任何说“代码更好”的问题。
我建议你首先重构你的代码 - 如果这样的代码发生在整个地方,也许它需要被转移到一个集中的函数中。如果dog.getName()委托给dog.collar()获取它的标签,最后是标签的名称,那么你只需要在一个地方修复这个bug(即使它不在领子上,狗也必须有一个名字,所以dog.getName应该能够遍历任何路径来解决你的问题 - 现在再次为了那些糟糕代码的NEXT点再做一次。
每当你看到自己在2个地方修补相同的代码时,就会出现因素问题。如果这只对每组属性发生一次(如果它已经完全分解并且是OO)那么它就不是一个严重的问题,只是几个补丁。
哎呀,这样的代码是不是违反了一些熟悉的规则?
答案 2 :(得分:1)
您可以使用闭包明确地将其实现为monad。
我在遇到你问题的同时遇到了这个问题 http://groovyconsole.appspot.com/script/205001
?对于空检查,安全解除引用显然在语法上更清晰,你可以用?:来结束链接而不是null,例如在这个上下文中的“”。
如果你想了解monad我会建议学习Haskell,然后你自然会开始看到这些概念如何在其他语言中使用。允许可变性的语言,即使功能性(例如Scala)经常展示“不纯”的解决方案而不是纯粹的功能解决方案。
答案 3 :(得分:-1)
Java中没有“安全解除引用”运算符。
我认为这是一件好事,因为“安全解除引用”通常是一种伪装的错误。你基本上有两种可能性:
就个人而言,我通常会将长方法链视为将您的代码重构为较小的,明确命名的方法(如果需要可以在内部包含正确的空值处理)的提示。在大多数情况下,这可能比引入monad更合理。