:toc: = 自定义语法元素 本节系统梳理在 QLExpress4 在自定义语法元素方面的接口和能力。 == 总览 * 自定义函数 ** 实现CustomFunction接口 ** 使用 Java 函数式接口 ** 通过注解扫描注册 ** 通过QLExpress脚本添加 ** 实现QLFunctionalVarargs * 自定义操作符 ** 实现CustomBinaryOperator ** 替换内置操作符 ** 使用 Java 函数式接口 ** 添加别名 ** 实现QLFunctionalVarargs * 扩展函数 ** 继承ExtensionFunction ** 实现QLFunctionalVarargs * 操作符与函数别名 == 自定义函数 === 实现CustomFunction接口 [source,java,indent=0] ---- include::../src/test/java/com/alibaba/qlexpress4/test/function/HelloFunction.java[] ---- [source,java,indent=0] ---- include::../src/test/java/com/alibaba/qlexpress4/Express4RunnerTest.java[tag=customComplexFunction] ---- === 使用 Java 函数式接口 [source,java,indent=0] ---- include::../src/test/java/com/alibaba/qlexpress4/docs/CustomItemsDocTest.java[tag=addFunctionWithJavaFunctional] ---- === 注解方式注册 [source,java,indent=0] ---- include::../src/test/java/com/alibaba/qlexpress4/Express4RunnerTest.java[tag=annoObj] ---- [source,java,indent=0] ---- include::../src/test/java/com/alibaba/qlexpress4/Express4RunnerTest.java[tag=addFunctionByAnnotationObject] ---- === 通过QLExpress脚本添加 [source,java,indent=0] ---- include::../src/test/java/com/alibaba/qlexpress4/docs/CustomItemsDocTest.java[tag=joinFunctionVarargsObj] ---- === 实现QLFunctionalVarargs [source,java,indent=0] ---- include::../src/test/java/com/alibaba/qlexpress4/docs/CustomItemsDocTest.java[tag=addFunctionByVarargs] ---- [source,java,indent=0] ---- include::../src/test/java/com/alibaba/qlexpress4/docs/CustomItemsDocTest.java[tag=addFunctionByVarargs] ---- == 自定义操作符 === 实现CustomBinaryOperator并设置优先级 [source,java,indent=0] ---- include::../src/test/java/com/alibaba/qlexpress4/docs/CustomItemsDocTest.java[tag=addOperatorWithPrecedence] ---- === 替换内置操作符 [source,java,indent=0] ---- include::../src/test/java/com/alibaba/qlexpress4/docs/CustomItemsDocTest.java[tag=replaceDefaultOperator] ---- === 使用 Java 函数式接口 [source,java,indent=0] ---- include::../src/test/java/com/alibaba/qlexpress4/docs/CustomItemsDocTest.java[tag=addOperatorBiFunction] ---- === 实现QLFunctionalVarargs [source,java,indent=0] ---- include::../src/test/java/com/alibaba/qlexpress4/docs/CustomItemsDocTest.java[tag=addOperatorByVarargs] ---- == 扩展函数 === 继承ExtensionFunction [source,java,indent=0] ---- include::../src/test/java/com/alibaba/qlexpress4/Express4RunnerTest.java[tag=defineExtensionFunctionByExtensionFunction] ---- === 实现QLFunctionalVarargs [source,java,indent=0] ---- include::../src/test/java/com/alibaba/qlexpress4/Express4RunnerTest.java[tag=defineExtensionFunctionByQLFunctionalVarargs] ---- == QLFunctionalVarargs:一个对象同时定义三类操作 同一个QLFunctionalVarargs对象可同时用作函数、操作符与扩展函数的实现,便于在多处复用统一的语义与实现。该能力来源于接口的可变参数设计,详见下方示例与接口定义。背景讨论参考 link:https://github.com/alibaba/QLExpress/issues/407[issue407]: [source,java,indent=0] ---- include::../src/test/java/com/alibaba/qlexpress4/docs/CustomItemsDocTest.java[tag=qlfunctionalvarargsAllInOne] ---- === 接口定义 [source,java,indent=0] ---- include::../src/main/java/com/alibaba/qlexpress4/api/QLFunctionalVarargs.java[] ---- == 操作符与函数别名(亦支持关键字别名) [source,java,indent=0] ---- include::../src/test/java/com/alibaba/qlexpress4/Express4RunnerTest.java[tag=addAlias] ---- == 说明与建议 - QLFunctionalVarargs 的定义模式下,扩展函数调用时实参列表首位是接收者对象,其后为调用参数;函数与操作符不含接收者。 - 自定义操作符的优先级需根据表达式期望进行设置,避免与已有运算规则产生混淆。 - 注解方式注册仅会处理公开方法,且重复名称将注册失败;批量注册返回结果中包含成功与失败清单。