按值傳遞函數參數,是拷貝參數的實際值到函數的形式參數的方法調用。在這種情況下,參數在函數內變化對參數不會有影響。
10余年的城中網站建設經驗,針對設計、前端、開發(fā)、售后、文案、推廣等六對一服務,響應快,48小時及時工作處理。營銷型網站的優(yōu)勢是能夠根據用戶設備顯示端的尺寸不同,自動調整城中建站的顯示方式,使網站能夠適用不同顯示終端,在瀏覽器中調整網站的寬度,無論在任何一種瀏覽器上瀏覽網站,都能展現優(yōu)雅布局與設計,從而大程度地提升瀏覽體驗。成都創(chuàng)新互聯公司從事“城中網站設計”,“城中網站推廣”以來,每個客戶項目都認真落實執(zhí)行。
默認情況下,Go編程語言使用調用通過值的方法來傳遞參數。在一般情況下,這意味著,在函數內碼不能改變用來調用所述函數的參數??紤]函數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;
}
現在,讓我們通過使實際值作為在以下示例調用函數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;
}
讓我們把上面的代碼放在一個C文件,編譯并執(zhí)行它,它會產生以下結果:
Before swap, value of a :100
Before swap, value of b :200
After swap, value of a :100
After swap, value of b :200
這表明,參數值沒有被改變,雖然它們已經在函數內部改變。
通過傳遞函數參數,即是拷貝參數的地址到形式參數的參考方法調用。在函數內部,地址是訪問調用中使用的實際參數。這意味著,對參數的更改會影響傳遞的參數。
要通過引用傳遞的值,參數的指針被傳遞給函數就像任何其他的值。所以,相應的,需要聲明函數的參數為指針類型如下面的函數swap(),它的交換兩個整型變量的值指向它的參數。
代碼如下:
/* 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 */
}
現在,讓我們調用函數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.
* 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 */
}
讓我們把上面的代碼放在一個C文件,編譯并執(zhí)行它,它會產生以下結果:
Before swap, value of a :100
Before swap, value of b :200
After swap, value of a :200
After swap, value of b :100
這表明變化的功能以及不同于通過值調用的外部體現的改變不能反映函數之外。
按數據類別有以下幾種數據類型:
按存儲方式也有兩大類數據類型:
值類型:變量直接存儲值。值類型的數據存儲在棧內存空間中,棧在函數調f返回后,內存會被釋放。
引用類型:變量存儲的是一個地址,這個地址存儲最終的值。引用數據類型的數據存儲在堆內存空間中,通過 GC 回收。
函數調用時申明的基礎類型均為值傳遞,如int,string,數組等,數據傳入函數后會重新copy一份,函數內的修改不會影響外面的變量,外部變量的修改也不會影響函數類的變量。
func main () {
myvar := [ 4 ] string {" test0 ", " test1 ", " test3 ", " test4 "}
go Test (myvar)
for i := 1 ; i
Golang的interface,和別的語言是不同的。它不需要顯式的implements,只要某個struct實現了interface里的所有函數,編譯器會自動認為它實現了這個interface。
SICP里詳細解釋了為什么同一個接口,需要根據不同的數據類型,有不同的實現;以及如何做到這一點。在這里沒有OO的概念,先把OO放到一邊,從原理上看一下這是怎么做到的。
先把大概原理放在這里,然后再舉例子。為了實現多態(tài),需要維護一張全局的查找表,它的功能是根據類型名和方法名,返回對應的函數入口。當我增加了一種類型,需要把新類型的名字、相應的方法名和實際函數入口添加到表里。這基本上就是所謂的動態(tài)綁定了,類似于C++里的vtable。對于SICP中使用的lisp語言來說,這些工作需要手動完成。而對于java,則通過implements完成了這項工作。而golang則用了更加激進的方式,連implements都省了,編譯器自動發(fā)現自動綁定。