欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

GScript?編寫標(biāo)準(zhǔn)庫(kù)示例詳解

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

版本更新

最近 GScript 更新了 v0.0.11 版本,重點(diǎn)更新了:

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

引言

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

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

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

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

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

使用 Docker

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

說(shuō)干就干,最后修改了 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í)行。

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

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

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

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

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

編寫 GScript 標(biāo)準(zhǔn)庫(kù)

接下來(lái)重點(diǎn)聊聊 GScript 標(biāo)準(zhǔn)庫(kù)的事情,其實(shí)編寫標(biāo)準(zhǔn)庫(kù)是一個(gè)費(fèi)時(shí)費(fèi)力的事情。

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

對(duì)寫 GScript 標(biāo)準(zhǔn)庫(kù)感謝的朋友可以當(dāng)做一個(gè)參考,這里我打了一個(gè)樣,先看下運(yùn)行效果:

// 字符串工具類
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);

其中的實(shí)現(xiàn)源碼基本上是借鑒了 Go 的標(biāo)準(zhǔn)庫(kù),先來(lái)看看 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ù)實(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ù)的組合運(yùn)用;

在寫標(biāo)準(zhǔn)庫(kù)的過(guò)程中還會(huì)有額外收獲,可以再次閱讀一遍 Go 標(biāo)準(zhǔn)庫(kù)的實(shí)現(xiàn)流程,換了一種語(yǔ)法實(shí)現(xiàn)出來(lái),會(huì)加深對(duì) Go 標(biāo)準(zhǔn)庫(kù)的理解。

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

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

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

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

相關(guān)文章

  • Go 自定義package包設(shè)置與導(dǎo)入操作

    Go 自定義package包設(shè)置與導(dǎo)入操作

    這篇文章主要介紹了Go 自定義package包設(shè)置與導(dǎo)入操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-05-05
  • golang的空標(biāo)識(shí)符理解

    golang的空標(biāo)識(shí)符理解

    今天小編就為大家分享一篇關(guān)于golang的空標(biāo)識(shí)符理解,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2019-04-04
  • 詳解Go語(yǔ)言如何利用高階函數(shù)寫出優(yōu)雅的代碼

    詳解Go語(yǔ)言如何利用高階函數(shù)寫出優(yōu)雅的代碼

    高階函數(shù)(Hiher-order?Function)定義為:滿足下列條件之一的函數(shù):接收一個(gè)或多個(gè)函數(shù)作為參數(shù);返回值是一個(gè)函數(shù)。本文為大家介紹了如何利用高階函數(shù)寫出優(yōu)雅的代碼,希望對(duì)大家有所幫助
    2023-01-01
  • Golang配置解析神器go?viper使用詳解

    Golang配置解析神器go?viper使用詳解

    viper是一個(gè)很完善的Go項(xiàng)目配置解決方案,很多著名的開源項(xiàng)目都在使用,比如Hugo,Docker都使用了該庫(kù),使用viper可以讓我們專注于自己的項(xiàng)目代碼,而不用自己寫那些配置解析代碼,本文給大家介紹Golang配置解析神器go?viper使用,感興趣的朋友一起看看吧
    2022-05-05
  • Go 如何基于IP限制HTTP訪問(wèn)頻率的方法實(shí)現(xiàn)

    Go 如何基于IP限制HTTP訪問(wèn)頻率的方法實(shí)現(xiàn)

    這篇文章主要介紹了Go 如何基于IP限制HTTP訪問(wèn)頻率的方法實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11
  • mayfly-go部署和使用詳解

    mayfly-go部署和使用詳解

    這篇文章主要介紹了mayfly-go部署和使用詳解,此處部署基于CentOS7.4部署,結(jié)合實(shí)例代碼圖文給大家講解的非常詳細(xì),需要的朋友可以參考下
    2022-09-09
  • Go之接口型函數(shù)用法

    Go之接口型函數(shù)用法

    這篇文章主要介紹了Go之接口型函數(shù)用法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • GO語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單TCP服務(wù)的方法

    GO語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單TCP服務(wù)的方法

    這篇文章主要介紹了GO語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單TCP服務(wù)的方法,實(shí)例分析了Go語(yǔ)言實(shí)現(xiàn)TCP服務(wù)的技巧,需要的朋友可以參考下
    2015-03-03
  • Go?easyjson使用及反射原理

    Go?easyjson使用及反射原理

    這篇文章主要介紹了Go?easyjson使用技巧,詳細(xì)介紹了go自帶JSON庫(kù)使用的反射原理,性能相對(duì)較差,可以使用easyjson代替,需要的朋友可以參考下
    2022-04-04
  • 談?wù)剬?duì)Golang IO讀寫的困惑

    談?wù)剬?duì)Golang IO讀寫的困惑

    這篇文章主要介紹了談?wù)剬?duì)Golang IO讀寫的困惑,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08

最新評(píng)論