《Go語言從入門到精通》Go語言與其他語言的結(jié)合運(yùn)用_第1頁
《Go語言從入門到精通》Go語言與其他語言的結(jié)合運(yùn)用_第2頁
《Go語言從入門到精通》Go語言與其他語言的結(jié)合運(yùn)用_第3頁
《Go語言從入門到精通》Go語言與其他語言的結(jié)合運(yùn)用_第4頁
《Go語言從入門到精通》Go語言與其他語言的結(jié)合運(yùn)用_第5頁
已閱讀5頁,還剩16頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

Go語言與其他語言的結(jié)合運(yùn)用Go語言從入門到精通了解Cgo了解Go語言與WebAssembly的結(jié)合運(yùn)用01CGO02SCRIPT03ASSEMBLYtarget目標(biāo)了解幾種Go語言中運(yùn)行的腳本語言目錄導(dǎo)航18.1CgoContentsCgo

直接調(diào)用C語言編寫的函數(shù)庫

Go語言最初最主要的優(yōu)勢之一可以直接利用龐大的C語言積累資源Cgo–先以類似注釋的語法加入C語言代碼package

main

/*#include

<stdio.h>#include

<stdlib.h>#include

<time.h>

//

是否初始化隨機(jī)數(shù)種子的標(biāo)志int

randomizeFlagG

=

0;

//

獲取一個隨機(jī)數(shù)int

getRandomInt(int

maxA)

{

if

(randomizeFlagG

==

0)

{

//

初始化隨機(jī)數(shù)種子

srand(time(NULL));

}

//

限制隨機(jī)數(shù)值范圍

int

rs

=

rand()%maxA;

//

為了演示,在C語言函數(shù)中輸出一下生成的隨機(jī)數(shù)

printf("%d\n",

rs);

return

rs;}

//

輸出一個字符串void

printString(char

*str)

{

printf("%s\n",

str);}

*/Cgo–然后再Go語言中調(diào)用import

"C"

import

(

"fmt"

"unsafe")

func

main()

{

//

調(diào)用C的標(biāo)準(zhǔn)庫函數(shù)puts來輸出

C.puts(C.CString("這是一個test."))

//

將Go語言字符串轉(zhuǎn)換為C語言格式的字符串

cStrT

:=

C.CString("測試字符串")

//

調(diào)用C語言中自定義的函數(shù)來輸出

C.printString(cStrT)

//

確保釋放C語言格式的字符串所占用的內(nèi)存空間

defer

C.free(unsafe.Pointer(cStrT))

//

調(diào)用C語言中定義的函數(shù)獲取一個隨機(jī)數(shù)

rs

:=

C.getRandomInt(20)

//

輸出該隨機(jī)數(shù)及其在Go語言中的類型

fmt.Printf("%T,

%#v\n",

rs,

rs)}直接引用C語言文件package

main

/*#include

"test.h"*/import

"C"

import

"tools"

func

main()

{

C.show3Times(C.CString(string(tools.ConvertBytesFromUTF8ToGB18030([]byte("[時間]")))))}C語言代碼在test.c中,頭文件是test.hGo語言中編寫函數(shù)供C語言調(diào)用package

main

import

(

"C"

"fmt"

"/topxeq/txtk")

//export

printInGofunc

printInGo(value

string)

{

fmt.Println(value)}

//export

getRandomIntfunc

getRandomInt(maxA

int)

int

{

return

txtk.GetRandomIntLessThan(maxA)}

//

必須要有一個主函數(shù)main,可以沒有內(nèi)容func

main()

{}gobuild-buildmode=c-shared-ocgo3.dllcgo3.go將生成cgo3.h和cgo3.dllC語言中調(diào)用Go函數(shù)的寫法#include

"cgo3.h"

#include

<stdio.h>#include

<string.h>

int

main(){

char

strT[]

=

"隨機(jī)數(shù)";

int

lenT

=

strlen(strT);

GoString

goStrT

=

{strT,

lenT};

printInGo(goStrT);

GoInt

randomT

=

getRandomInt(100);

printf("%s:

%lld\n",

strT,

randomT);

return

0;}Cgo的局限大多數(shù)數(shù)據(jù)類型在Go語言和C語言之間要做轉(zhuǎn)換才能正確使用一些數(shù)據(jù)類型存在差異,稍不注意容易產(chǎn)生混淆,例如C語言中的int一般相當(dāng)于Go語言中的int32,而longlong才相當(dāng)于Go語言中的int64

cgo中不能支持C語言中printf這類函數(shù)中使用的可變個數(shù)的參數(shù)形式,無法直接在Go語言中調(diào)用C語言中的printf這一類的函數(shù)。目錄導(dǎo)航18.2Go語言中運(yùn)行其他腳本語言Contentstengo腳本語言(/d5/tengo)sum

:=

0

//

變量初始化和賦值語句與Go語言基本一致

a

:=

0

//

循環(huán)語句也很像Go語言中的//

變量maxA是將從Go語言中傳遞進(jìn)來的for

a

<

maxA

{

sum

+=

a

a

++}

//

也有printf等內(nèi)置函數(shù)//

times函數(shù)是在Go語言中定義的//

這里演示了在腳本語言中調(diào)用Go語言中代碼的能力printf("%d\n",

times(2,

3,

4))創(chuàng)建tengo虛擬機(jī)并執(zhí)行腳本//

新建一個腳本運(yùn)行的虛擬機(jī)//

一般會編譯為字節(jié)碼準(zhǔn)備運(yùn)行s

:=

script.New([]byte(codeT))

//

向腳本執(zhí)行環(huán)境(虛擬機(jī)VM)中傳入變量maxA_

=

s.Add("maxA",

20)

//傳入準(zhǔn)備在虛擬機(jī)中執(zhí)行的Go語言編寫的函數(shù)times_

=

s.Add("times",

times)

//

執(zhí)行腳本c,

err

:=

s.Run()if

err

!=

nil

{

panic(err)}

//

獲取返回值(腳本中的sum變量)sumT

:=

c.Get("sum")

//

轉(zhuǎn)換類型后輸出fmt.Println(sumT.Int())實現(xiàn)JavaScript虛擬機(jī)的/robertkrimen/otto包vmT

:=

otto.New()//

新建Javascript虛擬機(jī)vmT.Set("a",

18)//

設(shè)置虛擬機(jī)中的變量a為數(shù)字18vmT.Set("text1",

"[計算結(jié)果]

")//

設(shè)置虛擬機(jī)中的變量text1為字符串

//

設(shè)置供虛擬中Javascript代碼調(diào)用的Go語言函數(shù)vmT.Set("getRandomInt",

func(call

otto.FunctionCall)

otto.Value

{

//

獲取調(diào)用該函數(shù)時傳入的參數(shù),maxA將作為生成隨機(jī)數(shù)的最大值上限

maxA,

_

:=

call.Argument(0).ToInteger()

randomNumberT

:=

rand.Intn(int(maxA))//

生成隨機(jī)整數(shù)

rs,

_

:=

otto.ToValue(randomNumberT)//

轉(zhuǎn)換為虛擬機(jī)中可以接受的類型

return

rs//

返回該值})

//

在虛擬機(jī)中運(yùn)行代碼vmT.Run(`

result1

=

a

+

2;

//

計算a+2的數(shù)值

console.log(text1

+

result1);

//

輸出信息

result2

=

getRandomInt(20);

//

調(diào)用Go語言中的函數(shù)獲取20以內(nèi)的隨機(jī)整數(shù)`)

//

從虛擬機(jī)中獲取變量的值if

valueT,

errT

:=

vmT.Get("result1");

errT

==

nil

{

if

valueIntT,

errT

:=

valueT.ToInteger();

errT

==

nil

{

fmt.Printf("result1:

%v\n",

valueIntT)

}}實現(xiàn)Lua語言虛擬機(jī)的/Shopify/go-lua包var

codeT

=

`--

輸出字符串print("開始運(yùn)行")

--

Lua中定義函數(shù)--

接受兩個參數(shù),并返回一個結(jié)果值function

AddTwice(a,

b)

return

a

+

b

+

bend

`

func

main()

{

vmT

:=

lua.NewState()

//

新建一個Lua虛擬機(jī)

lua.OpenLibraries(vmT)//

打開所有的Lua標(biāo)準(zhǔn)庫

//

執(zhí)行Lua腳本

if

errT

:=

lua.DoString(vmT,

codeT);

errT

!=

nil

{

panic(errT)

}

vmT.Global("AddTwice")//

獲取Lua中的函數(shù)

vmT.PushInteger(3)//

傳入?yún)?shù)

vmT.PushInteger(8)

vmT.Call(2,

1)//

調(diào)用該函數(shù),聲明有兩個參數(shù)和一個返回值

result2,

_

:=

vmT.ToInteger(1)//

獲取返回結(jié)果(參數(shù)中是結(jié)果序號)

fmt.Printf("返回結(jié)果為:%v",

result2)

vmT.Pop(1)//

從棧上彈出一個數(shù)值目錄導(dǎo)航18.3Go語言中直接執(zhí)行其他程序或調(diào)用系統(tǒng)命令Contents調(diào)用應(yīng)用程序或執(zhí)行系統(tǒng)命令//

分配用于存放調(diào)用程序輸出信息的緩沖區(qū)var

outBufT

bytes.Buffer

//

分配用于存放調(diào)用程序運(yùn)行發(fā)生錯誤時輸出錯誤信息的緩沖區(qū)var

errBufT

bytes.Buffer

//

創(chuàng)建執(zhí)行findstr命令的對象,第二個參數(shù)開始是命令行參數(shù)//

一個命令行參數(shù)作為exec.Command函數(shù)的一個參數(shù)cmdT

:=

exec.Command(`c:\Windows\System32\findstr.exe`,

`package`,

`c:\goprjs\src\tools\*.go`)

//

把調(diào)用程序的標(biāo)準(zhǔn)輸出指向outBufT//

標(biāo)準(zhǔn)輸出一般指的是程序正常執(zhí)行時輸出的信息cmdT.Stdout

=

&outBufT

//

把調(diào)用程序的標(biāo)準(zhǔn)錯誤輸出指向errBufT//

標(biāo)準(zhǔn)錯誤輸出一般指的是程序執(zhí)行出現(xiàn)異常時輸出的信息cmdT.Stderr

=

&errBufT

//

執(zhí)行該命令(或程序)errT

:=

cmdT.Run()使用操作系統(tǒng)的管道cmdT

:=

exec.Command(nameA,

argsA...)

pipeT,

errT

:=

cmdT.StdoutPipe()//

獲取該對象的標(biāo)準(zhǔn)輸出管道

readerT

:=

bufio.NewReader(pipeT)//

創(chuàng)建從管道中讀取內(nèi)容的bufio.Reader對象

go

func()

{//

啟動一個goroutine來讀取

for

{//

循環(huán)每次讀取一行,直至讀到io.EOF或出錯

inputT,

errT

:=

readerT.ReadString('\n')

if

errT

!=

nil

{

if

errT

==

io.EOF

{

return

}

tools.Printfln("從管道中讀取內(nèi)容時發(fā)生錯誤:%v",

errT)

return

}

tools.Printfln("%s",

inputT)

}}()

errT

=

cmdT.Start()目錄導(dǎo)航18.4Go語言與WebAssemblyContentsWebAssembly

簡稱Wasm,用其他語言編寫代碼,編譯成可以跨平臺執(zhí)行的特殊二進(jìn)制代碼在瀏覽器中執(zhí)行(JavaScript)WebAssemblyfmt.Printf("這是一個Go

WebAssembly的例子。\n")//

在瀏覽器的控制臺輸出信息

//

獲取網(wǎng)頁DOM對象中的輸入框var

input1

=

js.Global().Get("document").Call("getElementById",

"input1"

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論