真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

go語(yǔ)言調(diào)用函數(shù)方法 go 函數(shù)調(diào)用

go語(yǔ)言如何調(diào)用c函數(shù)

直接嵌入c源代碼到go代碼里面

十多年的承德網(wǎng)站建設(shè)經(jīng)驗(yàn),針對(duì)設(shè)計(jì)、前端、開(kāi)發(fā)、售后、文案、推廣等六對(duì)一服務(wù),響應(yīng)快,48小時(shí)及時(shí)工作處理。營(yíng)銷(xiāo)型網(wǎng)站建設(shè)的優(yōu)勢(shì)是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動(dòng)調(diào)整承德建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無(wú)論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計(jì),從而大程度地提升瀏覽體驗(yàn)。創(chuàng)新互聯(lián)建站從事“承德網(wǎng)站設(shè)計(jì)”,“承德網(wǎng)站推廣”以來(lái),每個(gè)客戶項(xiàng)目都認(rèn)真落實(shí)執(zhí)行。

package main

/*

#include stdio.h

void myhello(int i) {

printf("Hello C: %d\n", i);

}

*/

import "C"

import "fmt"

func main() {

C.myhello(C.int(12))

fmt.Println("Hello Go");

}

需要注意的是C代碼必須放在注釋里面

import "C"語(yǔ)句和前面的C代碼之間不能有空行

運(yùn)行結(jié)果

$ go build main.go ./main

Hello C: 12

Hello Go

分開(kāi)c代碼到單獨(dú)文件

嵌在一起代碼結(jié)構(gòu)不是很好看,很多人包括我,還是喜歡把兩個(gè)分開(kāi),放在不同的文件里面,顯得干凈,go源文件里面是go的源代碼,c源文件里面是c的源代碼。

$ ls

hello.c hello.h main.go

$ cat hello.h

void hello(int);

$ cat hello.c

#include stdio.h

void hello(int i) {

printf("Hello C: %d\n", i);

}

$ cat main.go

package main

// #include "hello.h"

import "C"

import "fmt"

func main() {

C.hello(C.int(12))

fmt.Println("Hello Go");

}

編譯運(yùn)行

$ go build ./main

Hello C: 12

Hello Go

編譯成庫(kù)文件

如果c文件比較多,最好還是能夠編譯成一個(gè)獨(dú)立的庫(kù)文件,然后go來(lái)調(diào)用庫(kù)。

$ find mylib main

mylib

mylib/hello.h

mylib/hello.c

main

main/main.go

編譯庫(kù)文件

$ cd mylib

# gcc -fPIC -shared -o libhello.so hello.c

編譯go程序

$ cd main

$ cat main.go

package main

// #cgo CFLAGS: -I../mylib

// #cgo LDFLAGS: -L../mylib -lhello

// #include "hello.h"

import "C"

import "fmt"

func main() {

C.hello(C.int(12))

fmt.Println("Hello Go");

}

$ go build main.go

運(yùn)行

$ export LD_LIBRARY_PATH=../mylib

$ ./main

Hello C: 12

Hello Go

在我們的例子中,庫(kù)文件是編譯成動(dòng)態(tài)庫(kù)的,main程序鏈接的時(shí)候也是采用的動(dòng)態(tài)庫(kù)

$ ldd main

linux-vdso.so.1 = (0x00007fffc7968000)

libhello.so = ../mylib/libhello.so (0x00007f513684c000)

libpthread.so.0 = /lib64/libpthread.so.0 (0x00007f5136614000)

libc.so.6 = /lib64/libc.so.6 (0x00007f5136253000)

/lib64/ld-linux-x86-64.so.2 (0x000055d819227000)

理論上講也是可以編譯成整個(gè)一靜態(tài)鏈接的可執(zhí)行程序,由于我的機(jī)器上缺少靜態(tài)鏈接的系統(tǒng)庫(kù),比如libc.a,所以只能編譯成動(dòng)態(tài)鏈接。

3.6 Go語(yǔ)言函數(shù)的延遲調(diào)用(Deferred Code)

在以下這段代碼中,我們操作一個(gè)文件,無(wú)論成功與否都需要關(guān)閉文件句柄。這里在三處不同的位置都調(diào)用了file.Close()方法,代碼顯得非常冗余。

我們利用延遲調(diào)用來(lái)優(yōu)化代碼。定義后的defer代碼,會(huì)在return之前返回,讓代碼顯得更加緊湊,且可讀性變強(qiáng),對(duì)上面的代碼改造如下:

我們通過(guò)這個(gè)示例來(lái)看一下延遲調(diào)用與正常代碼之間的執(zhí)行順序

先簡(jiǎn)單分析一下代碼邏輯:

從輸出中,我們可以觀察到如下現(xiàn)象:

從這個(gè)實(shí)例中,我們很明顯觀察到,defer語(yǔ)句是在return之前執(zhí)行

如果一個(gè)函數(shù)內(nèi)定義了多個(gè)defer,則調(diào)用順序?yàn)長(zhǎng)IFO(后進(jìn)先出)方式執(zhí)行。

仍然是相同的例子,但是在TestDefer中我們定義了三個(gè)defer輸出,根據(jù)LIFO原則,輸出的順序是3rd-2nd-1st,根據(jù)最后的結(jié)果,也是逆向向上執(zhí)行defer輸出。

就在整理這篇筆記的時(shí)候,發(fā)現(xiàn)了自己的認(rèn)知誤區(qū),主要是本節(jié)實(shí)例三中發(fā)現(xiàn)的,先來(lái)看一下英文的描述:

對(duì)于上面的這段話的理解:

下面是代碼執(zhí)行輸出,我們來(lái)一起分析一下:

雖然在a()函數(shù)內(nèi),顯示的返回了10,但是main函數(shù)中得到的結(jié)果是defer函數(shù)自增后的結(jié)果,我們來(lái)分析一下代碼:

在這篇文章的上一版,我曾經(jīng)嘗試用指針取解釋defer修改返回值的類(lèi)型,但是感覺(jué)不夠透徹,也讓閱讀者非常困惑,索性參考了一下go官方blog中的一篇文章,在此基礎(chǔ)上進(jìn)行了擴(kuò)展。如需要閱讀原文,可以參考下面的文章。

淺談Go語(yǔ)言函數(shù)與方法的區(qū)別

前段時(shí)間,我們實(shí)驗(yàn)室用go作為后臺(tái)開(kāi)發(fā)語(yǔ)言開(kāi)發(fā)了一個(gè)web項(xiàng)目,由于這是自己第一次使用go語(yǔ)言進(jìn)行開(kāi)發(fā),在開(kāi)發(fā)過(guò)程中,一味著追求完成任務(wù),在編碼的時(shí)候沒(méi)有太注重性能,雖然勉強(qiáng)實(shí)現(xiàn)了功能,但是對(duì)go語(yǔ)言的理解還是比較淺顯的。下面來(lái)談?wù)勛约簩?duì)go語(yǔ)言中函數(shù)與方法的理解。

普通函數(shù):

go函數(shù)可以返回多個(gè)值

值傳遞: 值傳遞是指在調(diào)用函數(shù)時(shí)將實(shí)際參數(shù)復(fù)制一份傳遞到函數(shù)中,這樣函數(shù)中如果對(duì)參數(shù)進(jìn)行修改,將不會(huì)影響到實(shí)際參數(shù)

引用傳遞: 引用傳遞是指在調(diào)用函數(shù)將實(shí)際參數(shù)的地址傳遞到函數(shù)中,那么在函數(shù)中對(duì)參數(shù)進(jìn)行的修改,將影響到實(shí)際參數(shù)。

一般來(lái)說(shuō)go語(yǔ)言函數(shù)的 接收者(也就是形參)一般放在函數(shù)名后面 ,不能將指針類(lèi)型的數(shù)據(jù)直接傳遞,也就是說(shuō)函數(shù)形參如果是值類(lèi)型,調(diào)用者必須使用值作為實(shí)參過(guò)來(lái),如果函數(shù)形參是指針類(lèi)型,則函數(shù)調(diào)用者需使用指針作為實(shí)參來(lái)調(diào)用。

普通方法:

接收者是在func關(guān)鍵字后面,而不是在函數(shù)名稱(chēng)后面,接收者可以是自己定義的一個(gè)類(lèi)型,這個(gè)類(lèi)型可以是struct、interface,一個(gè)方法就是一個(gè)包含了接收者的函數(shù),接收者可以是命名類(lèi)型或者是結(jié)構(gòu)體類(lèi)型的一個(gè)值或者是一個(gè)指針。

下面是一個(gè)例子來(lái)說(shuō)明方法和函數(shù)的區(qū)別(重點(diǎn))

Go語(yǔ)言中怎么通過(guò)一個(gè)字符串調(diào)用對(duì)應(yīng)名稱(chēng)的函數(shù)

按值傳遞函數(shù)參數(shù),是拷貝參數(shù)的實(shí)際值到函數(shù)的形式參數(shù)的方法調(diào)用。在這種情況下,參數(shù)在函數(shù)內(nèi)變化對(duì)參數(shù)不會(huì)有影響。

默認(rèn)情況下,Go編程語(yǔ)言使用調(diào)用通過(guò)值的方法來(lái)傳遞參數(shù)。在一般情況下,這意味著,在函數(shù)內(nèi)碼不能改變用來(lái)調(diào)用所述函數(shù)的參數(shù)??紤]函數(shù)swap()的定義如下。

代碼如下:

/* function definition to swap the values */

func swap(int x, int y) int {

var temp int

temp = x /* save the value of x */

x = y /* put y into x */

y = temp /* put temp into y */

return temp;

}

現(xiàn)在,讓我們通過(guò)使實(shí)際值作為在以下示例調(diào)用函數(shù)swap():

代碼如下:

package main

import "fmt"

func main() {

/* local variable definition */

var a int = 100

var b int = 200

fmt.Printf("Before swap, value of a : %d\n", a )

fmt.Printf("Before swap, value of b : %d\n", b )

/* calling a function to swap the values */

swap(a, b)

fmt.Printf("After swap, value of a : %d\n", a )

fmt.Printf("After swap, value of b : %d\n", b )

}

func swap(x, y int) int {

var temp int

temp = x /* save the value of x */

x = y /* put y into x */

y = temp /* put temp into y */

return temp;

}

讓我們把上面的代碼放在一個(gè)C文件,編譯并執(zhí)行它,它會(huì)產(chǎn)生以下結(jié)果:

Before swap, value of a :100

Before swap, value of b :200

After swap, value of a :100

After swap, value of b :200

這表明,參數(shù)值沒(méi)有被改變,雖然它們已經(jīng)在函數(shù)內(nèi)部改變。

通過(guò)傳遞函數(shù)參數(shù),即是拷貝參數(shù)的地址到形式參數(shù)的參考方法調(diào)用。在函數(shù)內(nèi)部,地址是訪問(wèn)調(diào)用中使用的實(shí)際參數(shù)。這意味著,對(duì)參數(shù)的更改會(huì)影響傳遞的參數(shù)。

要通過(guò)引用傳遞的值,參數(shù)的指針被傳遞給函數(shù)就像任何其他的值。所以,相應(yīng)的,需要聲明函數(shù)的參數(shù)為指針類(lèi)型如下面的函數(shù)swap(),它的交換兩個(gè)整型變量的值指向它的參數(shù)。

代碼如下:

/* function definition to swap the values */

func swap(x *int, y *int) {

var temp int

temp = *x /* save the value at address x */

*x = *y /* put y into x */

*y = temp /* put temp into y */

}

現(xiàn)在,讓我們調(diào)用函數(shù)swap()通過(guò)引用作為在下面的示例中傳遞數(shù)值:

代碼如下:

package main

import "fmt"

func main() {

/* local variable definition */

var a int = 100

var b int= 200

fmt.Printf("Before swap, value of a : %d\n", a )

fmt.Printf("Before swap, value of b : %d\n", b )

/* calling a function to swap the values.

* a indicates pointer to a ie. address of variable a and

* b indicates pointer to b ie. address of variable b.

*/

swap(a, b)

fmt.Printf("After swap, value of a : %d\n", a )

fmt.Printf("After swap, value of b : %d\n", b )

}

func swap(x *int, y *int) {

var temp int

temp = *x /* save the value at address x */

*x = *y /* put y into x */

*y = temp /* put temp into y */

}

讓我們把上面的代碼放在一個(gè)C文件,編譯并執(zhí)行它,它會(huì)產(chǎn)生以下結(jié)果:

Before swap, value of a :100

Before swap, value of b :200

After swap, value of a :200

After swap, value of b :100

這表明變化的功能以及不同于通過(guò)值調(diào)用的外部體現(xiàn)的改變不能反映函數(shù)之外。


分享標(biāo)題:go語(yǔ)言調(diào)用函數(shù)方法 go 函數(shù)調(diào)用
URL地址:http://weahome.cn/article/ddojcdj.html

其他資訊

在線咨詢(xún)

微信咨詢(xún)

電話咨詢(xún)

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部