流畅的 try-catch 块

huangapple go评论126阅读模式
英文:

Fluent try-catch block

问题

以下是翻译好的部分:

我在我的应用程序中有很多这种类型的代码:

String authUserId = null;

try {
  authUserId = webTokenService.readUserIdFromToken(app.getMasterKey(), authToken);
} catch (Exception e) {
  // 什么也不做
}

每个片段的目标是在方法没有抛出异常时赋值,否则为null。
虽然上面的代码有效,但显然看起来很冗余,不够简化。

哪个Java库可以使这段代码更加流畅?类似于:

String authUserId = Try.of(try -> {
   return webTokenService.readUserIdFromToken(app.getMasterKey(), authToken);
});

或者更简单的东西。

更新:

使用 Vavr 库

<dependency>
  <groupId>io.vavr</groupId>
  <artifactId>vavr</artifactId>
  <version>0.10.3</version>
</dependency>

使用以下代码解决了这个问题:

String authUserId = Try.of(() -> webTokenService.readUserIdFromToken(app.getMasterKey(), authToken)).get();
英文:

I have a lot of this type code in my app:

String authUserId = null;

try {
  authUserId = webTokenService.readUserIdFromToken(app.getMasterKey(), authToken);
} catch (Exception e) {
  // do nothing
}

With each fragment goal is to assign a value if the method did not throw, null otherwise.
And although the code above works it certainly looks redundant and not simplified.

What Java library can make this code more fluent? Like:

String authUserId = Try&lt;String&gt;.of(try -&gt; {
   return webTokenService.readUserIdFromToken(app.getMasterKey(), authToken);
});

or something more simpler.

UPDATE:

Using Vavr library

&lt;dependency&gt;
  &lt;groupId&gt;io.vavr&lt;/groupId&gt;
  &lt;artifactId&gt;vavr&lt;/artifactId&gt;
  &lt;version&gt;0.10.3&lt;/version&gt;
&lt;/dependency&gt;

Solved this with:

String authUserId = Try.of(() -&gt; webTokenService.readUserIdFromToken(app.getMasterKey(), authToken)).get();

答案1

得分: 2

由于默默吞噬异常是愚蠢的,不建议这样做。

完全可以自己编写这样的代码:

class ShootMyselfInLegToolkit {
    @FunctionalInterface
    public interface PermissiveSupplier<T> {
        T supply() throws Exception;
    }

    public <T> T ohMyLegs(PermissiveSupplier<T> supplier) {
        try {
            return supplier.supply();
        } catch (Exception itHurts) {
            return null; // 亲爱的上帝。
        }
    }
}

如果你真的想把它放到一个库中,尽管去做吧。

稍微不那么愚蠢的函数库工作方式如下:您提供一个(允许的 - Java 自己的 j.u.f.Supplier 不能做到这一点)供应商和一个异常处理程序,所以看起来像这样:

Tool.tryGet(() -> Files.readAllLines(Paths.get("foo.txt")), ioex -> { 处理异常的代码 });

你不能仅仅因为没有括号而认为这是“代码行数更少”和因此“更简单”的。这是一种非常奇怪的思维方式。

那么,用你的话来说,“流畅”究竟意味着什么?我认识这个术语是用于设置器、获取器和构建器方法,它的意思是:“没有 get/set 前缀”。显然,这不适用于这里,所以你显然认为它有其他意思。它不在 Java 语言规范中,所以也许你可以详细解释一下。

我无法理解这些东西中任何一个如何更容易理解或更容易编程,除了愚蠢的风格之争以外。我认为大多数人会同意,仅仅因为你发现 Java 社区中常用的风格令人讨厌而引入一堆疯狂的库 - 那是一种不好的方法。以非习惯用法编写代码是一个不好的主意,不管是哪种语言,也不管你有多么讨厌常用的风格。要么使用不同的语言,要么调整你的风格口味。也许说起来容易,但无论如何 - 这是远远更好的想法。

英文:

Given that silently swallowing exceptions is dumb, none.

It's entirely trivial to write such a thing yourself:

class ShootMyselfInLegToolkit {
    @FunctionalInterface
    public interface PermissiveSupplier&lt;T&gt; {
        T supply() throws Exception;
    }

    public &lt;T&gt; T ohMyLegs(PermissiveSupplier&lt;T&gt; supplier) {
        try {
            return supplier.supply();
        } catch (Exception itHurts) {
            return null; // dear lord.
        }
    }
}

If you really wanna shove that in a library, by all means.

The slightly-less-silly functional libraries work like this: You supply both a (permissive - java's own j.u.f.Supplier cannot do this) supplier and an exception handler, so it looks like:

Tool.tryGet(() -&gt; Files.readAllLines(Paths.get(&quot;foo.txt&quot;)), ioex -&gt; { code to handle the exception });

You don't just get to go: Hey, no brackets, so I never press enter, and therefore this is 'fewer lines of code' and therefore, 'simpler', that's.. well, a very strange mode of thinking you got there.

What, in your words, does 'fluent' even mean? I recognize the term as applied to setters, getters, and builder methods, and it means: "No get/set prefix". That obviously doesn't apply here, so you clearly think it means something else. It's not in the java lang spec, so perhaps elaborate.

I fail to see how any of this stuff is simpler to understand or easier to program for, aside from silly style fights. I'd think most would agree that introducing a whole bunch of crazy libraries JUST because you find the commonly used style in the java community abhorrent - that's a bad way out. Writing code in a non-idiomatic fashion is a bad idea, regardless of language and regardless of how much you hate the common style. Just use a different language, or adjust your style tastes. Easier said than done, perhaps, but nevertheless - the better idea, by far.

答案2

得分: 1

如果你完全吞下了异常,这实际上并不是最佳实践。关于来自Baeldung的异常,有一篇很好的文章

> 上述情况被称为吞掉异常。大多数情况下,我们这样做可能有点不太好,因为它没有解决问题,还会阻止其他代码解决问题。

我找到了一个,它实现了这种行为。然而,这个库已经有一段时间没有维护了。因此,我更推荐使用Vavr。仍然需要处理异常。从Baeldung那里也有进一步的教程。在文档中,有一个关于两个数相除的小例子:

int divide(int dividend, int divisor) {
    return dividend / divisor;
}

Try&lt;Integer&gt; divide(Integer dividend, Integer divisor) {
    return Try.of(() -&gt; dividend / divisor);
}
英文:

If you swallow the exception completely this is not really best practice. There is a nice article about Exception from Baeldung:

> The above is called swallowing an exception. Most of the time, it would be a little mean for us to do this because it doesn't address the issue and it keeps other code from being able to address the issue, too.

I have found a library that implements this behaviour. However, it has not been maintained for some time. For this reason I would rather recommend Vavr. It is still necessary to handle the exception. A further tutorial is also available from Baeldung. In the documentation there is a small example of dividing two numbers:

int divide(int dividend, int divisor) {
    return dividend / divisor;
}

Try&lt;Integer&gt; divide(Integer dividend, Integer divisor) {
    return Try.of(() -&gt; dividend / divisor);
}

huangapple
  • 本文由 发表于 2020年9月23日 03:20:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/64016422.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定