在这种情况下,如何处理Function <T,R>和省略号/ varargs?

ge

我的项目之一是投掷lambda在其中,我旨在简化@FunctionalInterfaces中潜在电位s的使用Stream,它在流中使用的唯一“缺陷”是它们引发了已检查的异常(就我而言,我宁可称其为缺陷,即您无法引发已检查的异常)从流,但这是另一个故事)。

因此,因为Function<T, R>我定义了这一点:

@FunctionalInterface
public interface ThrowingFunction<T, R>
    extends Function<T, R>
{
    R doApply(T t)
        throws Throwable;

    default R apply(T t)
    {
        try {
            return doApply(t);
        } catch (Error | RuntimeException e) {
            throw e;
        } catch (Throwable throwable) {
            throw new ThrownByLambdaException(throwable);
        }
    }
}

例如,这使我可以定义:

final ThrowingFunction<Path, Path> = Path::toRealPath;

(为什么Path::toRealPath……好吧,正是因为它带有省略号)。

不想在这里停下来,我想写点东西:

Throwing.function(Path::toRealPath).fallbackTo(Path::toAbsolutePath)

上面的NEARLY作品...阅读。

我也定义了这一点:

public abstract class Chainer<N, T extends N, C extends Chainer<N, T, C>>
{
    protected final T throwing;

    protected Chainer(final T throwing)
    {
        this.throwing = throwing;
    }

    public abstract C orTryWith(T other);

    public abstract <E extends RuntimeException> T orThrow(
        final Class<E> exclass);

    public abstract N fallbackTo(N fallback);

    public final <E extends RuntimeException> T as(final Class<E> exclass)
    {
        return orThrow(exclass);
    }
}

这是Functions的实现

public final class ThrowingFunctionChain<T, R>
    extends Chainer<Function<T, R>, ThrowingFunction<T, R>, ThrowingFunctionChain<T, R>>
    implements ThrowingFunction<T, R>
{
    public ThrowingFunctionChain(final ThrowingFunction<T, R> function)
    {
        super(function);
    }

    @Override
    public R doApply(final T t)
        throws Throwable
    {
        return throwing.doApply(t);
    }

    @Override
    public ThrowingFunctionChain<T, R> orTryWith(
        final ThrowingFunction<T, R> other)
    {
        final ThrowingFunction<T, R> function = t -> {
            try {
                return throwing.doApply(t);
            } catch (Error | RuntimeException e) {
                throw e;
            } catch (Throwable ignored) {
                return other.doApply(t);
            }
        };

        return new ThrowingFunctionChain<>(function);
    }

    @Override
    public <E extends RuntimeException> ThrowingFunction<T, R> orThrow(
        final Class<E> exclass)
    {

        return t -> {
            try {
                return throwing.doApply(t);
            } catch (Error | RuntimeException e) {
                throw e;
            } catch (Throwable throwable) {
                throw  ThrowablesFactory.INSTANCE.get(exclass, throwable);
            }
        };
    }

    @Override
    public Function<T, R> fallbackTo(final Function<T, R> fallback)
    {
        return t -> {
            try {
                return doApply(t);
            } catch (Error | RuntimeException e) {
                throw e;
            } catch (Throwable ignored) {
                return fallback.apply(t);
            }
        };
    }
}

到目前为止,一切都很好(尽管IDEA无法识别的代码orTryWith()为有效,但这是另一回事了)。

我还定义了一个名为的实用程序类Throwing,问题出在main()我作为测试编写的该类的中:

public final class Throwing
{
    private Throwing()
    {
        throw new Error("nice try!");
    }

    public static <T, R> ThrowingFunctionChain<T, R> function(
        final ThrowingFunction<T, R> function)
    {
        return new ThrowingFunctionChain<>(function);
    }

    public static void main(final String... args)
    {
        // FAILS TO COMPILE
        final Function<Path, Path> f = function(Path::toRealPath)
            .fallbackTo(Path::toAbsolutePath);
    }
}

现在,以上代码的错误消息是:

Error:(29, 48) java: incompatible types: cannot infer type-variable(s) T,R
    (argument mismatch; invalid method reference
      method toRealPath in interface java.nio.file.Path cannot be applied to given types
        required: java.nio.file.LinkOption[]
        found: java.lang.Object
        reason: varargs mismatch; java.lang.Object cannot be converted to java.nio.file.LinkOption)
Error:(29, 49) java: invalid method reference
  non-static method toRealPath(java.nio.file.LinkOption...) cannot be referenced from a static context
Error:(30, 25) java: invalid method reference
  non-static method toAbsolutePath() cannot be referenced from a static context

我无法在这里诊断出错误的确切原因,但对我来说,它似乎就像省略号一样;实际上,如果我这样做:

    final ThrowingFunctionChain<Path, Path> f = function(Path::toRealPath);

    try (
        final Stream<Path> stream = Files.list(Paths.get(""));
    ) {
        stream.map(f.fallbackTo(Path::toAbsolutePath))
            .forEach(System.out::println);
    }

然后编译:因此,这意味着Stream.map()确实将结果确认为Function...

那为什么不Throwing.function(Path::toRealPath).fallbackTo(Path::toAbsolutePath)编译呢?

霍尔格

您的代码片段

Function<Path, Path> f = function(Path::toRealPath).fallbackTo(Path::toAbsolutePath);

达到了规范中包含的Java 8类型推断的限制,因此它不是编译器错误。当您链接方法调用时,目标类型不起作用。由于该链的第一个方法是varargs方法,因此需要使用其目标类型来查找所需的调用签名。这种情况类似于您编写时的情况p->p.toRealPath(),其中调用的参数数是明确的,但是的类型p未知。两者都不在调用链中起作用(在最后一次调用中)

可以通过使第一个调用的类型显式化来解决,

Function<Path, Path> f = Throwing.<Path,Path>function(Path::toRealPath)
  .fallbackTo(Path::toAbsolutePath);

或者

ThrowingFunctionChain<Path, Path> f0 = function(Path::toRealPath);
Function<Path, Path> f = f0.fallbackTo(Path::toAbsolutePath);

或者

Function<Path, Path> f = function((Path p)->p.toRealPath())
    .fallbackTo(Path::toAbsolutePath);

或通过将方法调用链转换为未链接的方法调用,如下所述

public static <T, R> ThrowingFunctionChain<T, R> function(
    final ThrowingFunction<T, R> function)
{
    return new ThrowingFunctionChain<>(function);
}
public static <T, R> Function<T, R> function(
    final ThrowingFunction<T, R> function, Function<T, R> fallBack)
{
    return new ThrowingFunctionChain<>(function).fallbackTo(fallBack);
}
public static void main(final String... args)
{
    Function<Path, Path> f = function(Path::toRealPath, Path::toAbsolutePath);
}

当一个调用针对另一个调用的结果时,该规范故意拒绝了两个调用的类型推断,但是如果相同的表达式只是另一个调用的参数,则该规范起作用。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

处理省略号

来自分类Dev

如何在R中将list()转换为省略号?

来自分类Dev

如何让R识别省略号中的参数向量?

来自分类Dev

如何在R中将list()转换为省略号?

来自分类Dev

如何让R识别省略号中的参数向量?

来自分类Dev

Angular2类前面的省略号(在这种情况下为Collection)

来自分类Dev

R:如何在省略号中使用列表元素(如参数)?

来自分类Dev

R在call()中使用省略号...

来自分类Dev

如何为TD设置省略号

来自分类Dev

如何避免Dplyr中的省略号...?

来自分类Dev

如何使用文字溢出:省略号?

来自分类Dev

如何在Angular中使用省略号和标签实现(动态宽度)文本输入?

来自分类Dev

numpy 三维切片和索引以及省略号是如何工作的?

来自分类Dev

如何用省略号截断长文本,但总是在省略号后显示图标

来自分类Dev

在这种情况下,如何设置setInterval()和removeInterval()?

来自分类Dev

R:函数如何使用省略号(...)接受变量参数而不将其复制到内存中?

来自分类Dev

如何检查R中是否通过“ ...”(省略号)传递了任何参数?缺少(...)有效吗?

来自分类Dev

如何将省略号的内容保存在R中以用于深度嵌套的函数调用中?

来自分类Dev

在定义中使用省略号时,如何在R函数调用中捕获错误或未定义的参数

来自分类Dev

如何使用省略号传递参数并在R中的另一个环境中求值

来自分类Dev

如果发生溢出,如何设置UITextView的最大高度和固定宽度并强制省略号而不是滚动?

来自分类Dev

Reduce()和...(省略号)

来自分类Dev

考虑到省略号的出现如何计算句子

来自分类Dev

如何选择我的溢出省略号开始的位置

来自分类常见问题

如何对文本产生省略号效果

来自分类Dev

如何在嵌套函数中正确使用省略号

来自分类Dev

如何使用CSS实现单行省略号

来自分类Dev

如何阻止UILabel用省略号替换“ ...”

来自分类Dev

如何删除jQuery DataTables分页中的省略号?

Related 相关文章

  1. 1

    处理省略号

  2. 2

    如何在R中将list()转换为省略号?

  3. 3

    如何让R识别省略号中的参数向量?

  4. 4

    如何在R中将list()转换为省略号?

  5. 5

    如何让R识别省略号中的参数向量?

  6. 6

    Angular2类前面的省略号(在这种情况下为Collection)

  7. 7

    R:如何在省略号中使用列表元素(如参数)?

  8. 8

    R在call()中使用省略号...

  9. 9

    如何为TD设置省略号

  10. 10

    如何避免Dplyr中的省略号...?

  11. 11

    如何使用文字溢出:省略号?

  12. 12

    如何在Angular中使用省略号和标签实现(动态宽度)文本输入?

  13. 13

    numpy 三维切片和索引以及省略号是如何工作的?

  14. 14

    如何用省略号截断长文本,但总是在省略号后显示图标

  15. 15

    在这种情况下,如何设置setInterval()和removeInterval()?

  16. 16

    R:函数如何使用省略号(...)接受变量参数而不将其复制到内存中?

  17. 17

    如何检查R中是否通过“ ...”(省略号)传递了任何参数?缺少(...)有效吗?

  18. 18

    如何将省略号的内容保存在R中以用于深度嵌套的函数调用中?

  19. 19

    在定义中使用省略号时,如何在R函数调用中捕获错误或未定义的参数

  20. 20

    如何使用省略号传递参数并在R中的另一个环境中求值

  21. 21

    如果发生溢出,如何设置UITextView的最大高度和固定宽度并强制省略号而不是滚动?

  22. 22

    Reduce()和...(省略号)

  23. 23

    考虑到省略号的出现如何计算句子

  24. 24

    如何选择我的溢出省略号开始的位置

  25. 25

    如何对文本产生省略号效果

  26. 26

    如何在嵌套函数中正确使用省略号

  27. 27

    如何使用CSS实现单行省略号

  28. 28

    如何阻止UILabel用省略号替换“ ...”

  29. 29

    如何删除jQuery DataTables分页中的省略号?

热门标签

归档