最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

GScript?編寫標準庫示例詳解

 更新時間:2022年10月17日 09:35:48   作者:crossoverJie  
這篇文章主要為大家介紹了GScript?編寫標準庫示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

版本更新

最近 GScript 更新了 v0.0.11 版本,重點更新了:

  • Docker 運行環(huán)境
  • 新增了 byte 原始類型
  • 新增了一些字符串標準庫 Strings/StringBuilder
  • 數(shù)組切片語法:int[] b = a[1: len(a)];

引言

前段時間發(fā)布了 GScript 的在線 playground,

這是一個可以在線運行 GScript 腳本的網(wǎng)站,其本質(zhì)原理是接收用戶的輸入源碼從而在服務(wù)器上運行的服務(wù);這簡直就是后門大開的 XSS 攻擊,為保住服務(wù)器我設(shè)置了運行 API 的后端服務(wù)的用戶權(quán)限,這樣可以避免執(zhí)行一些惡意的請求。

但也避免不了一些用戶執(zhí)行了一些耗時操作,比如一個死循環(huán)、或者是我提供 demo 里的打印楊輝三角。

這本質(zhì)上是一個遞歸函數(shù),當打印的三角層數(shù)過高時便會非常耗時,同時也非常消耗 CPU。

有幾次我去檢查服務(wù)器時發(fā)現(xiàn)了幾個 CPU 過高的進程,基本上都是這樣的耗時操作,不可避免的會影響到服務(wù)器的性能。

使用 Docker

為了解決這類問題,很自然的就能想到可以使用 Docker,所有的資源都和宿主機是隔離開的,無論怎么瞎折騰也不會影響到宿主機。

說干就干,最后修改了 API 執(zhí)行腳本的地方:

    string fileName = d.unix("Asia/Shanghai") + "temp.gs" ;
    s.writeFile(fileName, body, 438);
    string pwd = s.getwd();
    // string res = s.command("gscript", fileName);
    string res = s.command("docker","run","--rm","-v", pwd+":/usr/src/gscript","-w","/usr/src/gscript", "crossoverjie/gscript","gscript", fileName);
    s.remove(fileName);
    r.body = res;
    r.ast = dumpAST(body);
    r.symbol=dumpSymbol(body);
    ctx.JSON(200, r);

主要修改的就是將直接執(zhí)行的 GScript 命令修改為了調(diào)用 docker 執(zhí)行。

但其實也還有改進空間,后續(xù)新增協(xié)程之后可以便可監(jiān)控運行時間,超時后便會自動 kill 進程。

我也將該 Docker 上傳到了 DockerHub,現(xiàn)在大家想在本地體驗 GScriptREPL 時也只需要運行Docker 就能使用。

docker pull crossoverjie/gscript
docker run --rm -it  crossoverjie/gscript:latest gscript

當然也可以執(zhí)行用 Docker 執(zhí)行 GScript 腳本:

docker run --rm -v $PWD:/usr/src/gscript -w /usr/src/gscript crossoverjie/gscript gscript {yourpath}/temp.gs

編寫 GScript 標準庫

接下來重點聊聊 GScript 標準庫的事情,其實編寫標準庫是一個費時費力的事情。

現(xiàn)在編譯器已經(jīng)提供了一些可用的內(nèi)置函數(shù),借由這些內(nèi)置函數(shù)寫一些常見的工具類是完全沒有問題的。

對寫 GScript 標準庫感謝的朋友可以當做一個參考,這里我打了一個樣,先看下運行效果:

// 字符串工具類
StringBuilder b = StringBuilder();
b.writeString("10");
b.writeString("20");
int l = b.writeString("30");
string s = b.String();
printf("s:%s, len=%d ",s,l);
assertEqual(s,"102030");
byte[] b2 = toByteArray("40");
b.WriteBytes(b2);
s = b.String();
assertEqual(s,"10203040");
println(s);
// Strings 工具類
Strings s = Strings();
string[] elems = {"name=xxx","age=xx"};
string ret = s.join(elems, "&");
println(ret);
assertEqual(ret, "name=xxx&age=xx");
bool b = s.hasPrefix("http://www.xx.com", "http");
println(b);
assertEqual(b,true);
b = s.hasPrefix("http://www.xx.com", "https");
println(b);
assertEqual(b,false);

其中的實現(xiàn)源碼基本上是借鑒了 Go 的標準庫,先來看看 StringBuilder 的源碼:

class StringBuilder{
    byte[] buf = [0]{};
    // append contents to buf, it returns the length of s
    int writeString(string s){
        byte[] temp = toByteArray(s);
        append(buf, temp);
        return len(temp);
    }
    // append b to buf, it returns the length of b.
    int WriteBytes(byte[] b){
        append(buf, b);
        return len(b);
    }
    // copies the buffer to a new.
    grow(int n){
        if (n > 0) {
            // when there is not enough space left.
            if (cap(buf) - len(buf) < n) {
                byte[] newBuf = [len(buf), 2*cap(buf)+n]{};
                copy(newBuf, buf);
                buf = newBuf;
            }
        }   
    }
    string String(){
        return toString(buf);
    }
}

主要就是借助了原始的數(shù)組類型以及 toByteArray/toString 字節(jié)數(shù)組和字符串的轉(zhuǎn)換函數(shù)實現(xiàn)的。

class Strings{
    // concatenates the elements of its first argument to create a single string. The separator
    // string sep is placed between elements in the resulting string.
    string join(string[] elems, string sep){
        if (len(elems) == 0) {
            return "";
        }
        if (len(elems) == 1) {
            return elems[0];
        }
        byte[] bs = toByteArray(sep);
        int n = len(bs) * (len(elems) -1);
        for (int i=0; i < len(elems); i++) {
            string s = elems[i];
            byte[] bs = toByteArray(s);
            n = n + len(bs);
        }
        StringBuilder sb = StringBuilder();
        sb.grow(n);
        string first = elems[0];
        sb.writeString(first);
        string[] remain = elems[1:len(elems)];
        for(int i=0; i < len(remain); i++){
            sb.writeString(sep);
            string r = remain[i];
            sb.writeString(r);
        }
        return sb.String();
    }
    // tests whether the string s begins with prefix.
    bool hasPrefix(string s, string prefix){
        byte[] bs = toByteArray(s);
        byte[] bp = toByteArray(prefix);    
        return len(bs) >= len(bp) && toString(bs[0:len(bp)]) == prefix;
    }
}

Strings 工具類也是類似的,都是一些內(nèi)置函數(shù)的組合運用;

在寫標準庫的過程中還會有額外收獲,可以再次閱讀一遍 Go 標準庫的實現(xiàn)流程,換了一種語法實現(xiàn)出來,會加深對 Go 標準庫的理解。

所以歡迎感興趣的朋友向 GScript 貢獻標準庫,由于我個人精力有限,實現(xiàn)過程中可能會發(fā)現(xiàn)缺少某些內(nèi)置函數(shù)或數(shù)據(jù)結(jié)構(gòu),這也沒關(guān)系,反饋 issue 后我會盡快處理。

由于目前 GScript 還不支持包管理,所以新增的函數(shù)可以創(chuàng)建 Class 來實現(xiàn),后續(xù)支持包或者是 namespace 之后直接將該 Class 遷移過去即可。

本文相關(guān)資源鏈接

以上就是GScript 編寫標準庫示例詳解的詳細內(nèi)容,更多關(guān)于GScript 編寫標準庫的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 使用Go語言實現(xiàn)在項目中隱藏敏感信息

    使用Go語言實現(xiàn)在項目中隱藏敏感信息

    在開發(fā)項目是,用戶信息管理是一個非常常見的場景,特別是當我們需要存儲和處理敏感信息時,本文主要介紹了如何使用Go語言實現(xiàn)隱藏敏感信息,需要的可以參考下
    2024-11-11
  • GO語言make()分配用法實例

    GO語言make()分配用法實例

    這篇文章主要介紹了GO語言make()分配用法,實例分析了make()的功能及使用技巧,需要的朋友可以參考下
    2015-02-02
  • Go歸并排序算法的實現(xiàn)方法

    Go歸并排序算法的實現(xiàn)方法

    歸并排序采用的也是分治的策略,把原本的問題先分解成一些小問題進行求解,再把這些小問題各自的答案修整到一起得到原本問題的答案,從而達到分而治之的目的,對Go歸并排序算法相關(guān)知識感興趣的朋友一起看看吧
    2022-04-04
  • Golang中的Unicode與字符串示例詳解

    Golang中的Unicode與字符串示例詳解

    這篇文章主要給大家介紹了關(guān)于Golang中Unicode與字符串的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家學習或者使用Golang具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2020-05-05
  • 一文讀懂go中semaphore(信號量)源碼

    一文讀懂go中semaphore(信號量)源碼

    這篇文章主要介紹了一文讀懂go中semaphore(信號量)源碼的相關(guān)知識,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-04-04
  • Go語言中 Channel 詳解

    Go語言中 Channel 詳解

    Go 語言中的 channel 是實現(xiàn) goroutine 間無鎖通信的關(guān)鍵機制,他使得寫多線程并發(fā)程序變得簡單、靈活、觸手可得。下面就個人理解對 channel 使用過程中應(yīng)該注意的地方進行一個簡要的總結(jié)。
    2018-10-10
  • Golang使用Gin實現(xiàn)文件上傳的示例代碼

    Golang使用Gin實現(xiàn)文件上傳的示例代碼

    本文我們主要介紹了Golang如何使用Gin實現(xiàn)文件上傳,Go標準庫net/http對文件上傳已經(jīng)提供了非常完善的支持,而Gin框架在其基礎(chǔ)上進一步封裝,因此使用Gin開發(fā)文件上傳功能時,只需要簡單幾行代碼便可以實現(xiàn),需要的朋友可以參考下
    2024-02-02
  • go語言實現(xiàn)一個最簡單的http文件服務(wù)器實例

    go語言實現(xiàn)一個最簡單的http文件服務(wù)器實例

    這篇文章主要介紹了go語言實現(xiàn)一個最簡單的http文件服務(wù)器的方法,實例分析了Go語言操作http的技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-03-03
  • Go語言實現(xiàn)AzDG可逆加密算法實例

    Go語言實現(xiàn)AzDG可逆加密算法實例

    這篇文章主要介紹了Go語言實現(xiàn)AzDG可逆加密算法,實例分析了AzDG可逆加密算法的實現(xiàn)技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-02-02
  • 使用GO操作MongoDB的方法

    使用GO操作MongoDB的方法

    這篇文章主要介紹了使用GO操作MongoDB,包括安裝MongoDB驅(qū)動程序連接mongodb的方法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-05-05

最新評論

河南省| 瓦房店市| 新竹市| 益阳市| 印江| 沁源县| 衡东县| 桃江县| 泰和县| 大田县| 梁平县| 盐山县| 济宁市| 嘉荫县| 五华县| 隆尧县| 鄢陵县| 九台市| 宝清县| 雷波县| 天气| 长宁区| 崇礼县| 巴林左旗| 石城县| 特克斯县| 灌南县| 左云县| 昌黎县| 佛学| 萨迦县| 荔浦县| 淅川县| 潜山县| 建昌县| 泾源县| 綦江县| 尤溪县| 惠来县| 乌兰浩特市| 股票|