设为首页收藏本站

LUPA开源社区

 找回密码
 注册
文章 帖子 博客
LUPA开源社区 首页 业界资讯 软件追踪 查看内容

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

2017-8-3 23:22| 发布者: joejoe0332| 查看: 688| 评论: 0|原作者: oschina|来自: oschina

摘要: 这次发布一下 2.1.0-beta,依然是个 beta 版本,原因参考这里:https://www.oschina.net/news/85315/febit-wit-2-0-0-beta。dependency groupIdorg.febit.wit/groupId artifactIdwit-core/artifactId version2.1.0-b ...

这次发布一下 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 吧,等有时间,再做几个例子传上去。

就这样~~


酷毙

雷人

鲜花

鸡蛋

漂亮
  • 快毕业了,没工作经验,
    找份工作好难啊?
    赶紧去人才芯片公司磨练吧!!

最新评论

关于LUPA|人才芯片工程|人才招聘|LUPA认证|LUPA教育|LUPA开源社区 ( 浙B2-20090187 浙公网安备 33010602006705号   

返回顶部