一個java和golang(go語言)通訊的例子。
來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。go語言是一個系統級語言,好處非常多。雖然是一個靜態編譯型語言,但可以像動態語言一樣寫程式,語言本身可以提供編寫應用程式所需的基本組件,而不用引入第三方的包。如果瞭解c++、java、python等,會對其簡潔和強大有更深的認識,c++實在過於繁瑣,java也沒有想象的簡單,python的效率和go不是一個數量級的。那麼多的特性,印象最深的就是其對並發的支援,優雅而高效。一般情況下並發通過進程、線程、基於非同步IO的回調來實現,進程和線程不能大量的建立,如超過1萬個系統資源就不堪重負了,回調可以儘可能少的建立線程,但用法不太符合自然習慣,比如boost 的asio就是一個很好的處理並發的架構,使用得當可以寫出高效優雅的伺服器程式。而go則在語言層級支援協程,協程是一種輕量級線程,可以建立百萬個而不會耗盡系統的資源。僅舉一簡單例子,go語言寫的伺服器程式會解析來自Java的json格式的資料,修改後返回:
go代碼:package mainimport ( "fmt" "net" "encoding/json")type Person struct{ Name string Id int Lks []string}func doServerStuff(conn net.Conn){ remote:=conn.RemoteAddr().String() fmt.Println(remote," connected!") for { buf:=make([]byte,512) size,err:=conn.Read(buf) if err!=nil{ fmt.Println("Read Error:",err.Error()); return } //fmt.Println("data from client:",string(buf),"size:",size) var person Person err=json.Unmarshal(buf[:size],&person) if err!=nil{ fmt.Println("Unmarshal Error:",err.Error()); return } fmt.Println("Person after Unmarshal:",person)
person.Id+=2
buf,err=json.Marshal(person) if err!=nil{ fmt.Println("Marshal Error:",err.Error()); return } conn.Write(buf) conn.Close() break }}func main(){ fmt.Println("Starting the server...") listener,err:=net.Listen("tcp","0.0.0.0:50000") if err!=nil{ fmt.Println("Listen Error:",err.Error()) return } for{ conn,err:=listener.Accept() if err!=nil{ fmt.Println("Accept Error:",err.Error()) return } go doServerStuff(conn) }}
通過關鍵字go即可完成並發的處理 ,go語言的哲學就是引入儘可能少的關鍵字和特性,編寫最少的程式碼完成更多的功能,並且還提供了很好的工程管理和單元測試,一個go命令搞定一切,不需要任何類似Makefile或build.xml或pom.xml(maven使用的) 之類的專案檔。因此go語言的作者們認為,c++沒什麼好學的,值得學習的是c語言。上面的代碼中需要注意的是:
1.struct的變數名要大寫
2.收到 socket的包之後要進行json解碼,需傳入實際的資料長度,如json.Unmarshal(buf[:size],&person)
Java代碼:
import java.net.*;import java.io.*;import net.sf.json.JSONObject;public class JSonTest {
/** * @param args */ private static Socket socket; private static BufferedReader in; private static PrintWriter out; public static void main(String[] args) { // TODO Auto-generated method stub JSONObject jsonObj=new JSONObject(); jsonObj.put("Name","liangyongs"); jsonObj.put("Id", 31); String[] likes={"java","golang","clang"}; jsonObj.put("Lks", likes); System.out.println("Object before sending to golang side:"); System.out.println(jsonObj); try{ socket=new Socket("127.0.0.1",50000); in=new BufferedReader(new InputStreamReader(socket.getInputStream())); out=new PrintWriter(socket.getOutputStream(),true); out.println(jsonObj); String line=in.readLine();
System.out.println("Object read from golang side:"); jsonObj=JSONObject.fromObject(line);
System.out.println(jsonObj.get("Id"));
socket.close();
}
catch(IOException e){
System.out.println(e);
}
}
}
這樣可以傳遞任意資料,即使go語言一方,不按照Java傳遞的資料格式定義結構體,也可以解析出部分能對應出的欄位,方便而簡單。
go語言可以使用gdb調試,也可以直接嵌套C語言,所以不用擔心支援go的庫少,c語言可以搞定就行了,而且c的資料類型可以很容易的轉換成go的資料類型,go也支援指標,支援goto,不久的將來可以在編譯器層級支援多核編程。