表達式引擎Aviator

Aviator是一個輕量級、高性能的Java表達式執行引擎, 本文內容主要來自於官方文檔

 

更多幹貨

 



簡介

Aviator是一個高性能、輕量級的 java 語言實現的表達式求值引擎, 主要用於各種表達式的動態求值。現在已經有很多開源可用的 java 表達式求值引擎,爲什麼還需要 Avaitor 呢?
Aviator的設計目標是輕量級和高性能,相比於Groovy、JRuby的笨重, Aviator非常小, 加上依賴包也才450K,不算依賴包的話只有 70K; 當然, Aviator的語法是受限的, 它不是一門完整的語言, 而只是語言的一小部分集合。
其次, Aviator的實現思路與其他輕量級的求值器很不相同, 其他求值器一般都是通過解釋的方式運行, 而Aviator則是直接將表達式編譯成Java 字節碼, 交給JVM去執行。簡單來說, Aviator的定位是介於Groovy這樣的重量級腳本語言和IKExpression這樣的輕量級表達式引擎 之間。
Aviator支持大部分運算操作符, 包括算術操作符、關係運算符、邏輯操作符、位運算符、正則匹配操作符(=~)、三元表達式(?:), 並且支持操作符的優先級和括號強制優先級, 具體請看後面的操作符列表, 支持自定義函數.

包依賴

Aviator依賴了commons-beanutils, 使用Aviator可以添加下面的maven依賴:


 
  1. <dependency>

  2. <groupId>com.googlecode.aviator</groupId>

  3. <artifactId>aviator</artifactId>

  4. <version>2.3.3</version>

  5. </dependency>

使用手冊

執行表達式

Aviator的使用都是集中通過com.googlecode.aviator.AviatorEvaluator這個入口類來處理, 最簡單的例子, 執行一個計算1+2+3的表達式:


 
  1. import com.googlecode.aviator.AviatorEvaluator;

  2. public class TestAviator {

  3. public static void main(String[] args) {

  4. Long result = (Long) AviatorEvaluator.execute("1+2+3");

  5. System.out.println(result);

  6. }

  7. }

細心的朋友肯定注意到結果是Long,而不是Integer。這是因爲Aviator的數值類型僅支持LongDouble, 任何整數都將轉換成Long, 任何浮點數都將轉換爲Double, 包括用戶傳入的變量數值。這個例子的打印結果將是正確答案6

使用變量

想讓Aviator對你say hello嗎? 很簡單, 傳入你的名字, 讓Aviator負責字符串的相加:


 
  1. public class TestAviator {

  2. public static void main(String[] args) {

  3. String yourName = "Michael";

  4. Map<String, Object> env = new HashMap<String, Object>();

  5. env.put("yourName", yourName);

  6. String result = (String) AviatorEvaluator.execute(" 'hello ' + yourName ", env);

  7. System.out.println(result); // hello Michael

  8. }

  9. }

上面的例子演示了怎麼向表達式傳入變量值, 表達式中的yourName是一個變量, 默認爲null, 通過傳入Map<String,Object>的變量綁定環境, 將yourName設置爲你輸入的名稱。 env 的key是變量名, value是變量的值。
上面例子中的'hello '是一個AviatorStringAviatorString是任何用單引號或者雙引號括起來的字符序列, String可以比較大小(基於unicode順序), 可以參與正則匹配, 可以與任何對象相加, 任何對象與String相加結果爲String。 String中也可以有轉義字符,如\n、\\、\' 等。


 
  1. AviatorEvaluator.execute(" 'a\"b' "); // 字符串 a"b

  2. AviatorEvaluator.execute(" \"a\'b\" "); // 字符串 a'b

  3. AviatorEvaluator.execute(" 'hello ' + 3 "); // 字符串 hello 3

  4. AviatorEvaluator.execute(" 'hello '+ unknow "); // 字符串 hello null

exec 方法

Aviator 2.2 開始新增加一個exec方法, 可以更方便地傳入變量並執行, 而不需要構造env這個map了:


 
  1. String name = "dennis";

  2. AviatorEvaluator.exec(" 'hello ' + yourName ", name); // hello dennis

只要在exec中按照變量在表達式中的出現順序傳入變量值就可以執行, 不需要構建Map了。

調用函數

Aviator 支持函數調用, 函數調用的風格類似 lua, 下面的例子獲取字符串的長度:

AviatorEvaluator.execute("string.length('hello')");  // 5

string.length('hello')是一個函數調用, string.length是一個函數, 'hello'是調用的參數。
再用string.substring來截取字符串:

AviatorEvaluator.execute("string.contains(\"test\", string.substring('hello', 1, 2))");  // true

通過string.substring('hello', 1, 2)獲取字符串'e', 然後通過函數string.contains判斷e是否在'test'中。可以看到, 函數可以嵌套調用。
Aviator 的內置函數列表請看後面。

自定義函數

Aviator 除了內置的函數之外,還允許用戶自定義函數,只要實現com.googlecode.aviator.runtime.type.AviatorFunction接口, 並註冊到AviatorEvaluator即可使用. AviatorFunction接口十分龐大, 通常來說你並不需要實現所有的方法, 只要根據你的方法的參 數個數, 繼承AbstractFunction類並override相應方法即可。

可以看一個例子,我們實現一個add函數來做數值的相加:


 
  1. public class TestAviator {

  2. public static void main(String[] args) {

  3. //註冊函數

  4. AviatorEvaluator.addFunction(new AddFunction());

  5. System.out.println(AviatorEvaluator.execute("add(1, 2)")); // 3.0

  6. System.out.println(AviatorEvaluator.execute("add(add(1, 2), 100)")); // 103.0

  7. }

  8. }

  9. class AddFunction extends AbstractFunction {

  10. @Override

  11. public AviatorObject call(Map<String, Object> env, AviatorObject arg1, AviatorObject arg2) {

  12. Number left = FunctionUtils.getNumberValue(arg1, env);

  13. Number right = FunctionUtils.getNumberValue(arg2, env);

  14. return new AviatorDouble(left.doubleValue() + right.doubleValue());

  15. }

  16. public String getName() {

  17. return "add";

  18. }

  19. }

註冊函數通過AviatorEvaluator.addFunction方法, 移除可以通過removeFunction

編譯表達式

上面提到的例子都是直接執行表達式, 事實上 Aviator 背後都幫你做了編譯並執行的工作。 你可以自己先編譯表達式, 返回一個編譯的結果, 然後傳入不同的env來複用編譯結果, 提高性能, 這是更推薦的使用方式:


 
  1. public class TestAviator {

  2. public static void main(String[] args) {

  3. String expression = "a-(b-c)>100";

  4. // 編譯表達式

  5. Expression compiledExp = AviatorEvaluator.compile(expression);

  6. Map<String, Object> env = new HashMap<String, Object>();

  7. env.put("a", 100.3);

  8. env.put("b", 45);

  9. env.put("c", -199.100);

  10. // 執行表達式

  11. Boolean result = (Boolean) compiledExp.execute(env);

  12. System.out.println(result); // false

  13. }

  14. }

通過compile方法可以將表達式編譯成Expression的中間對象, 當要執行表達式的時候傳入env並調用Expressionexecute方法即可。 表達式中使用了括號來強制優先級, 這個例子還使用了>用於比較數值大小, 比較運算符!=、==、>、>=、<、<=不僅可以用於數值, 也可以用於String、Pattern、Boolean等等, 甚至是任何用戶傳入的兩個都實現了java.lang.Comparable接口的對象之間。

編譯後的結果你可以自己緩存, 也可以交給 Aviator 幫你緩存, AviatorEvaluator內部有一個全局的緩存池, 如果你決定緩存編譯結果, 可以通過:

public static Expression compile(String expression, boolean cached)

cached設置爲true即可, 那麼下次編譯同一個表達式的時候將直接返回上一次編譯的結果。
使緩存失效通過:


 
  1. public static void invalidateCache(String expression)

  2.  

方法。

訪問數組和集合

可以通過中括號去訪問數組和java.util.List對象, 可以通過map.key訪問java.util.Mapkey對應的value, 一個例子:


 
  1. public static void main(String[] args) {

  2. final List<String> list = new ArrayList<String>();

  3. list.add("hello");

  4. list.add(" world");

  5. final int[] array = new int[3];

  6. array[0] = 0;

  7. array[1] = 1;

  8. array[2] = 3;

  9. final Map<String, Date> map = new HashMap<String, Date>();

  10. map.put("date", new Date());

  11. Map<String, Object> env = new HashMap<String, Object>();

  12. env.put("list", list);

  13. env.put("array", array);

  14. env.put("mmap", map);

  15. System.out.println(AviatorEvaluator.execute("list[0]+list[1]", env)); // hello world

  16. System.out.println(AviatorEvaluator.execute("'array[0]+array[1]+array[2]=' + (array[0]+array[1]+array[2])", env)); // array[0]+array[1]+array[2]=4

  17. System.out.println(AviatorEvaluator.execute("'today is ' + mmap.date ", env)); // today is Wed Feb 24 17:31:45 CST 2016

  18. }

三元操作符

Aviator 不提供if else語句, 但是提供了三元操作符?:用於條件判斷,使用上與 java 沒有什麼不同:

AviatorEvaluator.exec("a>0? 'yes':'no'", 1);  // yes

Aviator 的三元表達式對於兩個分支的結果類型並不要求一致,可以是任何類型,這一點與 java 不同。

正則表達式匹配

Aviator 支持類 Ruby 和 Perl 風格的表達式匹配運算,通過=~操作符, 如下面這個例子匹配 email 並提取用戶名返回:


 
  1. public static void main(String[] args) {

  2. String email = "[email protected]";

  3. Map<String, Object> env = new HashMap<String, Object>();

  4. env.put("email", email);

  5. String username = (String) AviatorEvaluator.execute("email=~/([\\w0-8]+)@\\w+[\\.\\w+]+/ ? $1 : 'unknow' ", env);

  6. System.out.println(username); // killme2008

  7. }

email與正則表達式/([\\w0-8]+@\\w+[\\.\\w+]+)/通過=~操作符來匹配,結果爲一個 Boolean 類 型, 因此可以用於三元表達式判斷,匹配成功的時候返回$1,指代正則表達式的分組 1,也就是用戶名,否則返回unknown

Aviator 在表達式級別支持正則表達式,通過//括起來的字符序列構成一個正則表達式,正則表 達式可以用於匹配(作爲=~的右操作數)、比較大小,匹配僅能與字符串進行匹配。匹配成功後, Aviator 會自動將匹配成功的分組放入$num的變量中,其中$0 指代整個匹配的字符串,而$1表示第一個分組,以此類推。

Aviator 的正則表達式規則跟 Java 完全一樣,因爲內部其實就是使用java.util.regex.Pattern做編譯的。

變量的語法糖

Aviator 有個方便用戶使用變量的語法糖, 當你要訪問變量a中的某個屬性b, 那麼你可以通過a.b訪問到, 更進一步, a.b.c將訪問變量ab屬性中的c屬性值, 推廣開來也就是說 Aviator 可以將變量聲明爲嵌套訪問的形式。
TestAviator類符合JavaBean規範, 並且是 public 的,我們就可以使用語法糖:


 
  1. public class TestAviator {

  2. int i;

  3. float f;

  4. Date date;

  5. // 構造方法

  6. public TestAviator(int i, float f, Date date) {

  7. this.i = i;

  8. this.f = f;

  9. this.date = date;

  10. }

  11. // getter and setter

  12.  
  13. public static void main(String[] args) {

  14. TestAviator foo = new TestAviator(100, 3.14f, new Date());

  15. Map<String, Object> env = new HashMap<String, Object>();

  16. env.put("foo", foo);

  17. System.out.println(AviatorEvaluator.execute("'foo.i = '+foo.i", env)); // foo.i = 100

  18. System.out.println(AviatorEvaluator.execute("'foo.f = '+foo.f", env)); // foo.f = 3.14

  19. System.out.println(AviatorEvaluator.execute("'foo.date.year = '+(foo.date.year+1990)", env)); // foo.date.year = 2106

  20. }

  21. }

nil 對象

nil是 Aviator 內置的常量,類似 java 中的null,表示空的值。nilnull不同的在於,在 java 中null只能使用在==、!=的比較運算符,而nil還可以使用>、>=、<、<=等比較運算符。 Aviator 規定,任何對象都比nil大除了nil本身。用戶傳入的變量如果爲null,將自動以nil替代。


 
  1. AviatorEvaluator.execute("nil == nil"); //true

  2. AviatorEvaluator.execute(" 3> nil"); //true

  3. AviatorEvaluator.execute(" true!= nil"); //true

  4. AviatorEvaluator.execute(" ' '>nil "); //true

  5. AviatorEvaluator.execute(" a==nil "); //true, a 是 null

nilString相加的時候,跟 java 一樣顯示爲 null

日期比較

Aviator 並不支持日期類型,如果要比較日期,你需要將日期寫字符串的形式,並且要求是形如 “yyyy-MM-dd HH:mm:ss:SS”的字符串,否則都將報錯。 字符串跟java.util.Date比較的時候將自動轉換爲Date對象進行比較:


 
  1. public static void main(String[] args) {

  2. Map<String, Object> env = new HashMap<String, Object>();

  3. final Date date = new Date();

  4. String dateStr = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SS").format(date);

  5. env.put("date", date);

  6. env.put("dateStr", dateStr);

  7. Boolean result = (Boolean) AviatorEvaluator.execute("date==dateStr", env);

  8. System.out.println(result); // true

  9. result = (Boolean) AviatorEvaluator.execute("date > '2010-12-20 00:00:00:00' ", env);

  10. System.out.println(result); // true

  11. result = (Boolean) AviatorEvaluator.execute("date < '2200-12-20 00:00:00:00' ", env);

  12. System.out.println(result); // true

  13. result = (Boolean) AviatorEvaluator.execute("date==date ", env);

  14. System.out.println(result); // true

  15. }

也就是說String除了能跟String比較之外,還能跟niljava.util.Date對象比較。

大數計算和精度

從 2.3.0 版本開始,aviator 開始支持大數字計算和特定精度的計算, 本質上就是支持java.math.BigIntegerjava.math.BigDecimal兩種類型, 這兩種類型在 aviator 中簡稱 爲big intdecimal類型。 類似99999999999999999999999999999999這樣的數字在 Java 語言裏是沒辦法編譯通過 的, 因爲它超過了Long類型的範圍, 只能用BigInteger來封裝。但是 aviator 通過包裝,可 以直接支持這種大整數的計算,例如:


 
  1. public static void main(String[] args) {

  2. System.out.println(AviatorEvaluator.exec("99999999999999999999999999999999 + 99999999999999999999999999999999"));

  3. }

結果爲類型big int的: 199999999999999999999999999999998

字面量表示

big intdecimal的表示與其他數字不同,兩條規則:

  • 以大寫字母N爲後綴的整數都被認爲是big int,如1N,2N,9999999999999999999999N等, 都是big int類型。
  • 超過long範圍的整數字面量都將自動轉換爲big int類型。
  • 以大寫字母M爲後綴的數字都被認爲是decimal, 如1M,2.222M, 100000.9999M等, 都是decimal類型。

用戶也可以通過變量傳入這兩種類型來參與計算。

運算

big intdecimal的運算,跟其他數字類型long,double沒有什麼區別,操作符仍然是一樣的。 aviator重載了基本算術操作符來支持這兩種新類型:


 
  1. public static void main(String[] args) {

  2. Object rt = AviatorEvaluator.exec("9223372036854775807100.356M * 2");

  3. System.out.println(rt + " " + rt.getClass()); // 18446744073709551614200.712 class java.math.BigDecimal

  4. rt = AviatorEvaluator.exec("92233720368547758074+1000");

  5. System.out.println(rt + " " + rt.getClass()); // 92233720368547759074 class java.math.BigInteger

  6. BigInteger a = new BigInteger(String.valueOf(Long.MAX_VALUE) + String.valueOf(Long.MAX_VALUE));

  7. BigDecimal b = new BigDecimal("3.2");

  8. BigDecimal c = new BigDecimal("9999.99999");

  9. rt = AviatorEvaluator.exec("a+10000000000000000000", a);

  10. System.out.println(rt + " " + rt.getClass()); // 92233720368547758089223372036854775807 class java.math.BigInteger

  11. rt = AviatorEvaluator.exec("b+c*2", b, c);

  12. System.out.println(rt + " " + rt.getClass()); // 20003.19998 class java.math.BigDecimal

  13. rt = AviatorEvaluator.exec("a*b/c", a, b, c);

  14. System.out.println(rt + " " + rt.getClass()); // 2.951479054745007313280155218459508E+34 class java.math.BigDecimal

  15. }

類型轉換和提升

big int或者decimal和其他類型的數字做運算的時候,按照long < big int < decimal < double的規則做提升, 也就是說運算的數字如果類型不一致, 結果的類型爲兩者之間更“高”的類型。例如:

  • 1 + 3N, 結果爲big int4N
  • 1 + 3.1M,結果爲decimal4.1M
  • 1N + 3.1M,結果爲decimal的 4.1M
  • 1.0 + 3N,結果爲double4.0
  • 1.0 + 3.1M,結果爲double4.1

decimal 的計算精度

Java 的java.math.BigDecimal通過java.math.MathContext支持特定精度的計算,任何涉及到金額的計算都應該使用decimal類型。

默認 Aviator 的計算精度爲MathContext.DECIMAL128,你可以自定義精度, 通過:

AviatorEvaluator.setMathContext(MathContext.DECIMAL64);

即可設置,更多關於decimal的精度問題請看java.math.BigDecimal的 javadoc 文檔。

強大的 seq 庫

aviator 擁有強大的操作集合和數組的 seq 庫。整個庫風格類似函數式編程中的高階函數。在 aviator 中, 數組以及java.util.Collection下的子類都稱爲seq,可以直接利用 seq 庫進行遍歷、過濾和聚合等操作。

例如,假設我有個 list:


 
  1. public static void main(String[] args) {

  2. Map<String, Object> env = new HashMap<String, Object>();

  3. ArrayList<Integer> list = new ArrayList<Integer>();

  4. list.add(3);

  5. list.add(20);

  6. list.add(10);

  7. env.put("list", list);

  8. Object result = AviatorEvaluator.execute("count(list)", env);

  9. System.out.println(result); // 3

  10. result = AviatorEvaluator.execute("reduce(list,+,0)", env);

  11. System.out.println(result); // 33

  12. result = AviatorEvaluator.execute("filter(list,seq.gt(9))", env);

  13. System.out.println(result); // [10, 20]

  14. result = AviatorEvaluator.execute("include(list,10)", env);

  15. System.out.println(result); // true

  16. result = AviatorEvaluator.execute("sort(list)", env);

  17. System.out.println(result); // [3, 10, 20]

  18. AviatorEvaluator.execute("map(list,println)", env);

  19. }

我們可以:

  • 求長度: count(list)
  • 求和: reduce(list,+,0)reduce函數接收三個參數,第一個是seq,第二個是聚合的函數,如+等,第三個是聚合的初始值
  • 過濾: filter(list,seq.gt(9)), 過濾出list中所有大於9的元素並返回集合; seq.gt函數用於生成一個謂詞,表示大於某個值
  • 判斷元素在不在集合裏: include(list,10)
  • 排序: sort(list)
  • 遍歷整個集合: map(list,println)map接受的第二個函數將作用於集合中的每個元素,這裏簡單地調用println打印每個元素

兩種運行模式

默認 AviatorEvaluator 以執行速度優先:

AviatorEvaluator.setOptimize(AviatorEvaluator.EVAL);

你可以修改爲編譯速度優先,這樣不會做編譯優化:

AviatorEvaluator.setOptimize(AviatorEvaluator.COMPILE);

調試信息

從 2.1.1.版本開始,Aviator允許設置輸出每個表達式生成的字節碼,只要設置tracetrue即可:

AviatorEvaluator.setTrace(true);

方便用戶做跟蹤和調試。默認是輸出到標準輸出,你可以改變輸出指向:

AviatorEvaluator.setTraceOutputStream(new FileOutputStream(new File("aviator.log")));

語法手冊

下面是 Aviator 詳細的語法規則定義。

數據類型

  • Number類型: 數字類型,支持四種類型,分別是long,double,java.math.BigInteger(簡稱 big int)java.math.BigDecimal(簡 稱 decimal),規則如下:
    • 任何以大寫字母 N 結尾的整數都被認爲是 big int
    • 任何以大寫字母 M 結尾的數字都被認爲是 decimal
    • 其他的任何整數都將被轉換爲 Long
    • 其他任何浮點數都將被轉換爲 Double
    • 超過 long 範圍的整數字面量都將自動轉換爲 big int 類型

其中 big int 和 decimal 是 2.3.0 版本開始引入的。數字還支持十六進制(以0x或者0X開頭的數字), 以及科學計數法,如1e-3等。 不支持其他進制。

  • String類型: 字符串類型,單引號或者雙引號括起來的文本串,如'hello world', 變量如果傳入的是String或者Character也將轉爲String類型
  • Bool類型: 常量truefalse,表示真值和假值,與 java 的Boolean.TRUEBoolean.False對應
  • Pattern類型: 正則表達式, 以//括起來的字符串,如/\d+/,內部 實現爲java.util.Pattern
  • 變量類型: 與 Java 的變量命名規則相同,變量的值由用戶傳入
  • nil類型: 常量nil,類似 java 中的null,但是nil比較特殊,nil不僅可以參與==、!=的比較, 也可以參與>、>=、<、<=的比較,Aviator 規定任何類型都大於nil除了nil本身,nil==nil返回true。 用戶傳入的變量值如果爲null,那麼也將作爲nil處理,nil打印爲null

操作符

算術運算符

Aviator 支持常見的算術運算符,包括+ - * / %五個二元運算符,和一元運算符-(負)。其中- * / %和一元的-僅能作用於Number類型。
+不僅能用於Number類型,還可以用於String的相加,或者字符串與其他對象的相加。
Aviator 規定,任何類型與String相加,結果爲String

邏輯運算符

Avaitor 的支持的邏輯運算符包括,一元否定運算符!,以及邏輯與的&&,邏輯或的||。邏輯運算符的操作數只能爲Boolean
&&||都執行短路規則。

關係運算符

Aviator 支持的關係運算符包括<, <=, >, >=以及==!= 。
關係運算符可以作用於Number之間、String之間、Pattern之間、Boolean之間、變量之間以及其他類型與nil之間的關係比較, 不同類型除了nil之外不能相互比較。

位運算符

Aviator 支持所有的 Java 位運算符,包括&, |, ^, ~, >>, <<, >>>

匹配運算符

匹配運算符=~用於StringPattern的匹配,它的左操作數必須爲String,右操作數必須爲Pattern。 匹配成功後,Pattern的分組將存於變量$num,num爲分組索引。

三元運算符

Aviator 沒有提供if else語句,但是提供了三元運算符?:,形式爲bool ? exp1: exp2。 其中bool必須爲Boolean類型的表達式, 而exp1exp2可以爲任何合法的 Aviator 表達式,並且不要求exp1exp2返回的結果類型一致。

內置函數

函數名稱 說明
sysdate() 返回當前日期對象 java.util.Date
rand() 返回一個介於 0-1 的隨機數,double 類型
print([out],obj) 打印對象,如果指定 out,向 out 打印, 否則輸出到控制檯
println([out],obj) 與 print 類似,但是在輸出後換行
now() 返回 System.currentTimeMillis
long(v) 將值的類型轉爲 long
double(v) 將值的類型轉爲 double
str(v) 將值的類型轉爲 string
date_to_string(date,format) 將 Date 對象轉化化特定格式的字符串,2.1.1 新增
string_to_date(source,format) 將特定格式的字符串轉化爲 Date 對 象,2.1.1 新增
string.contains(s1,s2) 判斷 s1 是否包含 s2,返回 Boolean
string.length(s) 求字符串長度,返回 Long
string.startsWith(s1,s2) s1 是否以 s2 開始,返回 Boolean
string.endsWith(s1,s2) s1 是否以 s2 結尾,返回 Boolean
string.substring(s,begin[,end]) 截取字符串 s,從 begin 到 end,如果忽略 end 的話,將從 begin 到結尾,與 java.util.String.substring 一樣。
string.indexOf(s1,s2) java 中的 s1.indexOf(s2),求 s2 在 s1 中 的起始索引位置,如果不存在爲-1
string.split(target,regex,[limit]) Java 裏的 String.split 方法一致,2.1.1 新增函數
string.join(seq,seperator) 將集合 seq 裏的元素以 seperator 爲間隔 連接起來形成字符串,2.1.1 新增函數
string.replace_first(s,regex,replacement) Java 裏的 String.replaceFirst 方法, 2.1.1 新增
string.replace_all(s,regex,replacement) Java 裏的 String.replaceAll 方法 , 2.1.1 新增
math.abs(d) 求 d 的絕對值
math.sqrt(d) 求 d 的平方根
math.pow(d1,d2) 求 d1 的 d2 次方
math.log(d) 求 d 的自然對數
math.log10(d) 求 d 以 10 爲底的對數
math.sin(d) 正弦函數
math.cos(d) 餘弦函數
math.tan(d) 正切函數
map(seq,fun) 將函數 fun 作用到集合 seq 每個元素上, 返回新元素組成的集合
filter(seq,predicate) 將謂詞 predicate 作用在集合的每個元素 上,返回謂詞爲 true 的元素組成的集合
count(seq) 返回集合大小
include(seq,element) 判斷 element 是否在集合 seq 中,返回 boolean 值
sort(seq) 排序集合,僅對數組和 List 有效,返回排 序後的新集合
reduce(seq,fun,init) fun 接收兩個參數,第一個是集合元素, 第二個是累積的函數,本函數用於將 fun 作用在集合每個元素和初始值上面,返回 最終的 init 值
seq.eq(value) 返回一個謂詞,用來判斷傳入的參數是否跟 value 相等,用於 filter 函數,如filter(seq,seq.eq(3)) 過濾返回等於3 的元素組成的集合
seq.neq(value) 與 seq.eq 類似,返回判斷不等於的謂詞
seq.gt(value) 返回判斷大於 value 的謂詞
seq.ge(value) 返回判斷大於等於 value 的謂詞
seq.lt(value) 返回判斷小於 value 的謂詞
seq.le(value) 返回判斷小於等於 value 的謂詞
seq.nil() 返回判斷是否爲 nil 的謂詞
seq.exists() 返回判斷不爲 nil 的謂詞

相關鏈接

GitHub上的資料

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章