這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
1.當標識符(包括常量、變數、類型、函數名、結構欄位等等)以一個大寫字母開頭,如:Group1,那麼使用這種形式的標識符的對象就可以被外部包的代碼所使用(用戶端程式需要先匯入這個包),這被稱為匯出(像物件導向語言中的 public);標識符如果以小寫字母開頭,則對包外是不可見的,但是他們在整個包的內部是可見並且可用的(像物件導向語言中的 protected )。
注意要分清是否跨包
2.
package mainvar x, y intvar ( // 這種因式分解關鍵字的寫法一般用於聲明全域變數 a int b bool)var c, d int = 1, 2var e, f = 123, "hello"//這種不帶聲明格式的只能在函數體中出現//g, h := 123, "hello"func main(){ g, h := 123, "hello" println(x, y, a, b, c, d, e, f, g, h)}
3.全域變數是允許聲明但不使用,局部變數不能重新聲明而且聲明了必須要使用
4.空白標識符 也被用於拋棄值,如值 5 在:, b = 5, 7 中被拋棄。
_ 實際上是一個唯寫變數,你不能得到它的值。這樣做是因為 Go 語言中你必須使用所有被聲明的變數,但有時你並不需要使用從一個函數得到的所有傳回值。
5.常量可以用len(), cap(), unsafe.Sizeof()常量計算運算式的值。常量運算式中,函數必須是內建函數,否則編譯不過:
package mainimport "unsafe"const ( a = "abc" b = len(a) c = unsafe.Sizeof(a))func main(){ println(a, b, c)}
6.iota
iota,特殊常量,可以認為是一個可以被編譯器修改的常量。
在每一個const關鍵字出現時,被重設為0,然後再下一個const出現之前,每出現一次iota,其所代表的數字會自動增加1。
package mainimport "fmt"func main() { const ( a = iota //0 b //1 c //2 d = "ha" //獨立值,iota += 1 e //"ha" iota += 1 f = 100 //iota +=1 g //100 iota +=1 h = iota //7,恢複計數 i //8 ) fmt.Println(a,b,c,d,e,f,g,h,i)}
7.指標變數與變數地址
package mainimport "fmt"func main() { var a int = 4 var b int32 var c float32 var ptr *int /* 運算子執行個體 */ fmt.Printf("第 1 行 - a 變數類型為 = %T\n", a ); fmt.Printf("第 2 行 - b 變數類型為 = %T\n", b ); fmt.Printf("第 3 行 - c 變數類型為 = %T\n", c ); /* & 和 * 運算子執行個體 */ ptr = &a /* 'ptr' 包含了 'a' 變數的地址 */ fmt.Printf("a 的值為 %d\n", a); fmt.Printf("*ptr 為 %d\n", *ptr); a=5 fmt.Printf("ptr 為 %d\n", ptr);//825741050416 fmt.Printf("*ptr 為 %d\n", *ptr);//5 *ptr=7 fmt.Println(*ptr,a)//7 7}
8 . if不強制加括弧
package mainimport "fmt"func main() { var a int = 100; if a < 20 { fmt.Printf("a 小於 20\n" ); } else if a>100{ fmt.Printf("a > 100\n" ); }else{ fmt.Printf("其他" ); }}
9.for 迴圈
package mainimport "fmt"func main() { var b int = 15 var a int numbers := [6]int{1, 2, 3, 5} /* for 迴圈 */ for a := 0; a < 10; a++ { fmt.Printf("a 的值為: %d\n", a) } for a < b { a++ fmt.Printf("a 的值為: %d\n", a) } //range可以對 slice、map、數組、字串等進行迭代迴圈 for i,x:= range numbers { fmt.Printf("第 %d 位 x 的值 = %d\n", i,x) } for{ fmt.Printf("無限迴圈") }}
goto不推薦用
package mainimport "fmt"func main() { /* 定義局部變數 */ var a int = 10 /* 迴圈 */ LOOP: for a < 20 { if a == 15 { /* 跳過迭代 */ a = a + 1 goto LOOP } fmt.Printf("a的值為 : %d\n", a) a++ } }
10 . 函數
package mainimport "fmt"func swap(x int, y string) (string, int) { return y, x}func swap1(x , y string) (string, string) { return y, x}func swap2(y string) string { return y}func main() { a, b := swap(1, "Kumar") fmt.Println(a, b)}
11.閉包
package mainimport "fmt"func getSequence() func() int { i:=0 return func() int { i+=1 return i }}func main(){ /* nextNumber 為一個函數,函數 i 為 0 */ nextNumber := getSequence() /* 調用 nextNumber 函數,i 變數自增 1 並返回 */ fmt.Println(nextNumber()) fmt.Println(nextNumber()) fmt.Println(nextNumber()) /* 建立新的函數 nextNumber1,並查看結果 */ nextNumber1 := getSequence() fmt.Println(nextNumber1()) fmt.Println(nextNumber1())}
12.函數方法,是否可以理解成java對象內部方法
package mainimport ( "fmt" )/* 定義函數 */type Circle struct { radius float64}func main() { var c1 Circle c1.radius = 10.00 fmt.Println("Area of Circle(c1) = ", c1.getArea())}//該 method 屬於 Circle 類型對象中的方法func (c Circle) getArea() float64 { //c.radius 即為 Circle 類型對象中的屬性 return 3.14 * c.radius * c.radius}
13.全域變數,同一個包內不能重名,不然編譯報錯
pointer類型變數預設值為nil
14.數組
package mainimport "fmt"func main() { var n [10]int /* n 是一個長度為 10 的數組 */ var i,j int /* 為數組 n 初始化元素 */ for i = 0; i < 10; i++ { n[i] = i + 100 /* 設定元素為 i + 100 */ } /* 輸出每個數組元素的值 */ for j = 0; j < 10; j++ { fmt.Printf("Element[%d] = %d\n", j, n[j] ) }}
15.再次強調指標
package mainimport "fmt"func main() { /* 定義局部變數 */ var a int = 100 var b int= 200 fmt.Printf("交換前 a 的值 : %d\n", a ) fmt.Printf("交換前 b 的值 : %d\n", b ) /* 調用函數用於交換值 * &a 指向 a 變數的地址 * &b 指向 b 變數的地址 */ swap(&a, &b); fmt.Printf("交換後 a 的值 : %d\n", a ) fmt.Printf("交換後 b 的值 : %d\n", b )}func swap(x *int, y *int) { var temp int temp = *x /* 儲存 x 地址的值 */ *x = *y /* 將 y 賦值給 x */ *y = temp /* 將 temp 賦值給 y */}
x = y只是值交換,為啥?因為它們指向的地址是a/b,不同的地址
“在Java裡面參數傳遞都是按值傳遞”這句話的意思是:按值傳遞是傳遞的值的拷貝,按引用傳遞其實傳遞的是引用的地址值,所以統稱按值傳遞
不同於java如果想達到引用傳遞的效果,go要加上指標符號*才可以
16.結構體
package mainimport "fmt"type Books struct { title string author string subject string book_id int}func main() { var Book1 Books /* Declare Book1 of type Book */ var Book2 Books /* Declare Book2 of type Book */ /* book 1 描述 */ Book1.title = "Go 語言" Book1.author = "www.runoob.com" Book1.subject = "Go 語言教程" Book1.book_id = 6495407 /* book 2 描述 */ Book2.title = "Python 教程" Book2.author = "www.runoob.com" Book2.subject = "Python 語言教程" Book2.book_id = 6495700 /* 列印 Book1 資訊 */ printBook(&Book1) /* 列印 Book2 資訊 */ printBook(&Book2)}func printBook( book *Books ) { fmt.Printf( "Book title : %s\n", book.title); fmt.Printf( "Book author : %s\n", book.author); fmt.Printf( "Book subject : %s\n", book.subject); fmt.Printf( "Book book_id : %d\n", book.book_id);}
17 切片
像java的list
package mainimport "fmt"func main() { var numbers = make([]int,3,5) printSlice(numbers) s :=[] int {1,2,3 } printSlice(s) var numbers1 []int printSlice(numbers1) if(numbers1== nil){ fmt.Println("切片是空的") } /* 列印子切片從索引1(包含) 到索引3(不包含)*/ fmt.Println("s[1:3] ==", s[1:3]) /* 預設下限為 0*/ fmt.Println("s[:3] ==", s[:3]) /* 預設上限為 len(s)*/ fmt.Println("s[2:] ==", s[2:]) numbers=append(numbers, 0,1,2,3,4,5,6) fmt.Println(numbers,cap(numbers)) /* 建立切片 numbersc 是之前切片的兩倍容量*/ numbersc := make([]int, len(numbers), (cap(numbers))*2) /* 拷貝 numbers 的內容到 numbersc */ copy(numbersc,numbers) fmt.Println(numbersc)}func printSlice(x []int){ fmt.Printf("len=%d cap=%d slice=%v\n",len(x),cap(x),x)//len=3 cap=5 slice=[0 0 0]}
18 map
package mainimport "fmt"func main() { var countryCapitalMap map[string]int /* 建立集合 */ countryCapitalMap = make(map[string]int) /* map 插入 key-value 對,各個國家對應的首都 */ countryCapitalMap["France"] = 1 countryCapitalMap["Italy"] = 2 countryCapitalMap["Japan"] = 3 countryCapitalMap["India"] = 4 delete(countryCapitalMap,"India"); /* 使用 key 輸出 map 值 */ for country := range countryCapitalMap { fmt.Println("Capital of",country,"is",countryCapitalMap[country]) } /* 查看元素在集合中是否存在 */ captial, ok := countryCapitalMap["United States"] /* 如果 ok 是 true, 則存在,否則不存在 */ if(ok){ fmt.Println("Capital of United States is", captial) }else { fmt.Println("Capital of United States is not present") }}
19 介面
package mainimport ( "fmt")type Phone interface { call()}type NokiaPhone struct {}func (nokiaPhone NokiaPhone) call() { fmt.Println("I am Nokia, I can call you!")}type IPhone struct {}func (iPhone IPhone) call() { fmt.Println("I am iPhone, I can call you!")}func main() { var phone Phone phone = new(NokiaPhone) phone.call() phone = new(IPhone) phone.call()}
20 異常
package mainimport ( "fmt" "errors")func main() { var err error = errors.New("this is a new error") //由於已經實現了error介面的方法 因此可以直接調用對應的方法 fmt.Println(err.Error())}
21 包內其他檔案的變數和方法隨便用,跨包則要通過“packageName.”方式引用了
22 工程檔案下要有main包,且main包下檔案不能包含重複main方法