1. XenForo 1.5.14 中文版——支持中文搜索!现已发布!查看详情
  2. Xenforo 爱好者讨论群:215909318 XenForo专区

新闻 Wit 2.1.0-beta 发布,Java 模板引擎(原 Webit Script) 下载

本帖由 漂亮的石头2017-08-03 发布。版面名称:软件资讯

  1. 漂亮的石头

    漂亮的石头 版主 管理成员

    注册:
    2012-02-10
    帖子:
    488,014
    赞:
    47
    这次发布一下 2.1.0-beta, 依然是个 beta 版本, 原因参考这里: https://www.oschina.net/news/85315/febit-wit-2-0-0-beta.

    <dependency>
    <groupId>org.febit.wit</groupId>
    <artifactId>wit-core</artifactId>
    <version>2.1.0-beta</version>
    </dependency>

    本次更新带来一个新语法:


    • 函数引用操作符 ::

    和 Java8 中新增的函数引用操作符是同一个概念, `Math::max` `String::valueOf` 这样, 就得到了一个函数的引用,

    不仅仅是静态函数, 构造函数也可以 `StringBuilder::new`, 成员函数也可以 `String::length`, 还可以带包名 `java.util.List::size`,当然 如果 `@import java.util.List;` 之后可以简写成 `List::size`.

    那么怎么吃?
    可以清蒸, 可以凉拌...
    哦不, 可以直接调用 `Math::max(x, y)`,
    也可以赋值到变量后再用 `var func = String::length; echo func("hi");`
    当然啦, 必须是 `public` 的方法才可以!

    和 `native` 有啥区别?
    当前的 native 一个函数引用, 是需要指定参数类型的, 例如: `var func = native String::valueOf(Integer)`
    使用这个从操作符就不需要了, 当存在不用参数类型的重载时, 会根据传入的参数类型选择一个 "比较合适的" 函数来调用 (恩, 到底选比较复杂, 目前是根据转换权重来算的, 想了解的可以看一下源代码)
    性能方面, 对于控制欲比较强的小伙伴,也可以考虑 native

    那个 `.~` 操作符有啥区别?

    `.~` 是一个比较 freestyle 的存在, 类型&函数 都是运行时才去取的, 以 `obj.~size()` 为例, 运行的时候根据 `obj` 的类型取名为 `size` 的函数, 是 List 是 Map 只要有名为 size 的 public 的成员函数就可以, 如果有不同参数类型的重载, 同样会根据实际的传参适配一个

    '::' 就比较中规中矩了, 指定了哪个类型, 编译成语法书的时候就从那个类型上提前找出有哪些同名的函数, 理论上性能比较好, 但是如果是成员方法, 第一个参数必须是实例本身, 用起来就很麻烦:
    `Map::size(map)`, 而 `map.~size()` 就比较简单

    差不多了, 来看几个例子吧:

    {
    @import org.febit.wit.util.StringUtil;

    var max = Math::max;

    assertEquals(max(1,2), 2);
    assertEquals(Math::max(1,2), 2);
    assertEquals(Math::min(1,2), 1);
    assertEquals(String::length("1234"), 4);
    assertEquals(String::valueOf("1234"), "1234");
    assertEquals(String::valueOf(1234), "1234");

    assertEquals(Integer::parseInt("1234"), 1234);
    assertEquals(Long::parseLong("1234"), 1234L);
    assertEquals(StringUtil::format("[0]={}, [1]={}, [2]:{}", ["aaaa", "bbb", 2]), "[0]=aaaa, [1]=bbb, [2]:2");
    }
    {
    var new_stringbuilder = native new StringBuilder();
    var buf = new_stringbuilder();

    buf.~append("123").~append(456);
    assertEquals("123456", buf.~toString());
    assertEquals("123456", StringBuilder::toString(buf));
    }
    {
    var buf = StringBuilder::new();
    StringBuilder::append(StringBuilder::append(buf, "123"), "233");
    assertEquals("123233", StringBuilder::toString(buf));

    buf = StringBuilder::new("233");
    assertEquals("233", buf.~toString());

    buf = StringBuilder::new(123);
    assertEquals(123, buf.~capacity());
    }

    好了, 有同学就问了, "现在前后端都分离了, 你做这个破东西有啥用?"

    papapa, 敲黑板! 对于前后端分离, 我是双手赞成! 实际上在做这个模板引擎之前, 作为青涩的全栈小码农, 就已经在实践前后端分离了.
    那时候, 只是只是为了偷懒, 做了个代码生成器 (https://github.com/febit/febit-generator), 迭代了几个版本, 用了各种模板引擎, 后来跟人拌了几句嘴, 决定自己做个模板引擎.

    那么, 除了做代码生成器, 还能用来做什么?
    渲染一些必须在后端渲染的邮件什么的
    当脚本引擎来用, 执行一些动态脚本, 你看, 只有 330kB 大小, 嵌到系统根本没压力嘛

    当规则引擎来用, 取出持久化的每个字段的表达式, 拼成脚本然后执行得到结果

    放个例子出来:
    https://github.com/febit/wit-toys

    感兴趣的话, 关注一下: https://github.com/febit 吧, 等有时间, 再做几个例子传上去.

    就这样~~
    Wit 2.1.0-beta 发布,Java 模板引擎(原 Webit Script)下载地址
     
正在加载...