這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
面向Java開發人員的GO編程
英文原文在此www.nada.kth.se/~snilsson/go_for_java_programmers
譯文同步至http://blog.csdn.net/kkkloveyou/article/details/8256649
http://bbs.gocn.im/thread-52-1-1.html
=======================以下本文========================.
- Hello stack (example)
- Conceptual differences
- Syntax
- Constants
- Structs
- Pointers
- Slices
|
- Making values
- Methods and interfaces
- Errors
- Panic and recover
- Goroutines and channels
- Concurrency (example)
|
本文旨在協助JAVA開發人員迅速掌握Go語言.
開始用一個很容易能被所有的Java程式員認出的例子來突出特色,然後對GO的架構給出了詳細的的描述,最後用一個例子來說明GO結構中沒有與Java直接對應處。
Hello stack (一個棧的例子)
為了吊起你的胃口,我們用一個麻雀雖小,五髒俱全和符合習慣的例子對應這個Stack.java程式
// 包collection實現了產生棧.package collection// 零值棧是一個空棧,準備被使用.type Stack struct { data []interface{}}// Push函數將x添加到棧頂.func (s *Stack) Push(x interface{}) { s.data = append(s.data, x)}// Pop函數是將棧頂元素移除並返回.// 在Pop函數執行在空棧時,會被一個運行時的error警示.func (s *Stack) Pop() interface{} { i := len(s.data) - 1 res := s.data[i] s.data[i] = nil // 避免記憶體泄露 s.data = s.data[:i] return res}// Size函數返回棧中元素的個數func (s *Stack) Size() int { return len(s.data)}
stack.go
- 頂級聲明出現之前,直接的評論是文檔注釋。他們是純文字。.
- 對於聲明,你把名字寫在類型後面.
struct
對應Java中的類, 但struct組成不是方法而只能是變數.
- T
interface{}
類型對應Java的Object
. 在GO中它被所有的類型所實現,而不僅僅是參考型別.
- 程式碼片段
(s*Stack)
聲明了一個方法,接收者s
對應Java中的this
.
- 操作符
:=
聲明並初始化了一個變數. 它的類型可以從初始設定式中推匯出.
這裡是一個的Hello world程式,示範了如何使用collection.Stack
的抽象資料類型.
package collection_testimport ( collection "." "fmt")func Example() { var s collection.Stack s.Push("world") s.Push("hello, ") for s.Size() > 0 { fmt.Print(s.Pop()) } fmt.Println() //輸出: hello, world}
example_test.go
概念上的差異
- Go的構造器沒有類。Go 用structs和interfaces來替代執行個體化方法,類的繼承機制,動態方法尋找.也可用於Java使用泛型介面
- Go提供所有類型的指標的值,而不只是對象和數組。對於任何類型
T
,有一個相應的指標類型*T
表示指標指向類型T
的值。
- Go允許任何類型都有方法而沒有裝箱的限制 方法receiver,在Java中對應
this
可以是直接值或者是指標.
- 數組在Go就是值. 當一個數組被當做函數的參數時,這個函數接收到的是數組的拷貝而不是它的指標. 然而在實踐中,函數經常使用slices作為參數; slices引用了基礎數組.
- 該語言提供了字串,一個字串行為就像一個位元組片,但是是不可改變的。
- 該語言中的雜湊表被稱作maps.
- 該語言提供了獨立啟動並執行線程goroutines和他們之間的通訊渠道channels.
- 某些類型(maps, slices, 和 channels)是按引用傳遞,而不是值。也就是說,傳遞一個map到函數並而不是拷貝map,如果函數修改了map,將被調用者看到變化。在Java術語來說,可以認為這是一個map的引用.
- Go提供了兩種存取層級對應Java的public和包的private.如果它的命名是大寫字母開頭就是最進階別public,反之就是包的private.
- 作為替換Java中的異常機制, Go採用了類型error值來表示事件,如檔案結尾,和運行時的panics來表示運行時的錯誤,如數組越界等.
- Go不支援隱式類型轉換。混合使用不同類型的操作需要顯式轉換.
- Go不支援函數重載。在同一範圍內的函數和方法必須具有唯一的名稱.
- Go使用
nil
表示無效的指標,類似於Java使用null
.
句法
聲明
聲明是跟Java是相反的。你在類型後面再寫名稱,型別宣告從左往右更容易讀
Go與Java相對應的
var v1 int |
int v1; |
var v2 *int |
Integer v2; |
var v3 string |
String v3 = ""; |
var v4 [10]int |
int[] v4 = new int[10]; // v4 在Go中是一個值. |
var v5 []int |
int[] v5; |
var v6 *struct { a int } |
C v6; // Given: class C { int a; } |
var v7 map[string]int |
HashMap<String,Integer> v7; |
var v8 func(a int) int |
F v8; // Given: interface F { int f(int a); } |
聲明的一般形式是一個關鍵字後面跟著被聲明對象的名字.這個關鍵字是const
,type
,var
, 或者func
. 您也可以使用一個關鍵字,後面的括弧中跟著一系列聲明.
var ( n int x float64)
當聲明一個函數,你必須提供每個參數的名稱,或者不提供任何參數的名稱,你不能提供了一些而忽略了另外一些名字。 您可以組合幾個相同類型的名稱:
func f(i, j, k int, s, t string)
一個變數可以在聲明時初始化。當這樣做時,指定的變數的類型是允許的,但不是必需的。當未指定類型,預設的是初始設定式的類型.
var v9 = *v2
如果一個變數沒有立即初始化,必須要制定類型。那樣的情況下,它它會被隱式初始化該類型的零值zero value(0
,nil
,""
, 等.). Go不存在未初始化的變數.
短聲明
在函數中,一個短的聲明句法是:=
表示.
v10 := v1
這等效於
var v10 = v1
函數類型
在Go中,函數都是一等公民。Go的函數類型表示一組所有具有相同的參數和傳回型別的函數.
type binOp func(int, int) intvar op binOpadd := func(i, j int) int { return i + j }op = addn = op(100, 200) // n = 100 + 200
多重分配
GO允許多重分配。在右邊的運算式會在評估後,再分配到任何的左運算元。
i, j = j, i //交換i和j.
函數可以具有多個傳回值,表示由括弧中的列表。返回的值可以儲存分配給一個變數列表。
func f() (i int, pj *int) { ... }v1, v2 = f()
空白標識符
空白標識符提供了一種忽略多值運算式傳回值的方式,用底線表示: The blank identifier, represented by the underscore character, provides a way to ignore values returned by a multi-valued expression:
v1, _ = f() // 忽略f()返回的第二個值.
分號和格式
為了消除對分號和格式不必要的擔憂,你可能會用gofmt
程式來寫GO風格的標準代碼, 雖然這種風格看起來很古怪,但熟悉了之後最終會像其他語言風格一樣變得舒服
Go的代碼在實際中很多出現分號。嚴格來說,Go所有的聲明都用分號結束。但是Go毫無疑問會在每個非空白行的結尾插入一個分號,除非它還沒有完. 這樣做的後果是,在某些情況下,Go不允許斷行。 舉例,你可能會像下面這樣寫:
func g(){ //無效的;“{”應該是在前面那一行。}
在g()
後面會被插入一個分號,這樣就使他像是一個函式宣告而不是函數定義了 類似的,你不能這樣寫:
if n == 0 {}else { // 無效的; "else {" 應該是在前面那一行。}
在}
後和else
前面會插入一個分號,導致句法錯誤.
===================未完待續.......==========
===================轉載註明出處=============
2012-12-4