前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Trino lambda表达式使用学习小结

Trino lambda表达式使用学习小结

作者头像
skyyws
发布2022-05-20 08:52:18
4260
发布2022-05-20 08:52:18
举报
文章被收录于专栏:skyyws的技术专栏

Trino中使用了很多的lambda表达式的写法,这点与Impala非常不同。这里简单学习了一些场景下的lambda表达式的用法。具体的例子如下:

代码语言:javascript
复制
private final JdbcApiStats getTableNames = new JdbcApiStats();

public JdbcApiStats getGetTableNames()
{
    return getTableNames;
}

public List<SchemaTableName> getTableNames(ConnectorSession session, Optional<String> schema)
{
    return stats.getGetTableNames().wrap(() -> delegate().getTableNames(session, schema));
}

函数本体只有一行代码,但是却完成了多个动作,这里主要用到的就是lambda表达式的写法,新手阅读起来会非常困难,我们一步一步拆解来看。首先通过getGetTableNames()方法获取到了一个JdbcApiStats类型的变量,然后调用其wrap方法。传入的参数是一个lambda表达式,即() -> delegate().getTableNames(session, schema)。这个表达式不需要参数,返回值是一个List集合。我们看下JdbcApiStats这个类的内容,如下所示:

代码语言:javascript
复制
@ThreadSafe
public class JdbcApiStats
{
    private final TimeStat time = new TimeStat(MILLISECONDS);
    private final CounterStat failures = new CounterStat();

    public <V, E extends Exception> V wrap(ThrowingCallable<V, E> callable)
            throws E
    {
        try (TimeStat.BlockTimer ignored = time.time()) {
            return callable.call();
        }
        catch (Exception e) {
            failures.update(1);
            throw e;
        }
    }

    public <E extends Exception> void wrap(ThrowingRunnable<E> callable)
            throws E
    {
        try (TimeStat.BlockTimer ignored = time.time()) {
            callable.run();
        }
        catch (Exception e) {
            failures.update(1);
            throw e;
        }
    }

    @Managed
    @Nested
    public TimeStat getTime()
    {
        return time;
    }

    @Managed
    @Nested
    public CounterStat getFailures()
    {
        return failures;
    }

    public interface ThrowingCallable<V, E extends Exception>
    {
        V call() throws E;
    }

    public interface ThrowingRunnable<E extends Exception>
    {
        void run() throws E;
    }
}

这里针对有返回值和无返回值的情况,定义了两个interface,分别是:ThrowingCallable和ThrowingRunnable,分别只有一个abstract method,这就是我们通常所说的函数式接口,有且仅有一个抽象方法。然后用这两个interface分别作为参数,构造了两个wrap函数。同时,进行了一些时间和失败次数的状态统计。再回到最初的labmda代码,我们其实就可以拆解为如下的几行代码:

代码语言:javascript
复制
public List<SchemaTableName> getTableNames(ConnectorSession session, Optional<String> schema)
{
    JdbcApiStats.ThrowingCallable callable = () -> delegate().getTableNames(session, schema);
    List<SchemaTableName> list = (List<SchemaTableName>) stats.getGetTableNames().wrap(callable);
    return list;
}

可以看到,这里将lambda显示转换为了ThrowingCallable这个interface类型的变量,然后传入到wrap函数。最后,将返回值显示转换为List,这里对应的就是ThrowingCallable中的V。在原先的写法中,编译器可以直接就从delegate().getTableNames()推导出返回值的类型,因此不需要显示转换。而ThrowingCallable中的call也就对应了delegate().getTableNames(),这里函数名称不一定必须是call,也可以换成其他的名称,但是只能有一个abstract method。如果我们再增加一个abstract method,例如V call2() throws E,编辑器就会报错,如下所示:

这样的使用好处就是,对于不同动作的相同wrap,就可以直接通过同一个JdbcApiStats来实现,非常方便:

代码语言:javascript
复制
@Override
public Optional<JdbcTableHandle> getTableHandle(ConnectorSession session, SchemaTableName schemaTableName)
{
    return stats.getGetTableHandle().wrap(() -> delegate().getTableHandle(session, schemaTableName));
}

@Override
public List<JdbcColumnHandle> getColumns(ConnectorSession session, JdbcTableHandle tableHandle)
{
    return stats.getGetColumns().wrap(() -> delegate().getColumns(session, tableHandle));
}

Trino的代码中用了很多函数式编程和lambda特性,后续有时间再继续研究学习。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-02-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档