go语言是一个系统级语言,好处非常多。虽然是一个静态编译型语言,但可以像动态语言一样写程序,语言本身可以提供编写应用程序所需的基本组件,而不用引入第三方的包。如果了解c++、java、python等,会对其简洁和强大有更深的认识,c++实在过于繁琐,java也没有想象的简单,python的效率和go不是一个数量级的。那么多的特性,印象最深的就是其对并发的支持,优雅而高效。一般情况下并发通过进程、线程、基于异步IO的回调来实现,进程和线程不能大量的创建,如超过1万个系统资源就不堪重负了,回调可以尽可能少的创建线程,但用法不太符合自然习惯,比如boost
的asio就是一个很好的处理并发的框架,使用得当可以写出高效优雅的服务器程序。而go则在语言级别支持协程,协程是一种轻量级线程,可以创建百万个而不会耗尽系统的资源。仅举一简单例子,go语言写的服务器程序会解析来自Java的json格式的数据,修改后返回:
go代码:
go代码:
package main
import (
"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)
buf,err=json.Marshal(person)
person.Id+=2
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语言。
通过关键字go即可完成并发的处理 ,go语言的哲学就是引入尽可能少的关键字和特性,编写最少的代码完成更多的功能,并且还提供了很好的工程管理和单元测试,一个go命令搞定一切,不需要任何类似Makefile或build.xml或pom.xml(maven使用的) 之类的项目文件。因此go语言的作者们认为,c++没什么好学的,值得学习的是c语言。
上面的代码中需要注意的是:
1.struct的变量名要大写
2.收到 socket的包之后要进行json解码,需传入实际的数据长度,如json.Unmarshal(buf[:size],&person)
Java代码:
socket.close();
}
catch(IOException e){
System.out.println(e);
}
}
}
这样可以传递任意数据,即使go语言一方,不按照Java传递的数据格式定义结构体,也可以解析出部分能对应出的字段,方便而简单。
go语言可以使用gdb调试,也可以直接嵌套C语言,所以不用担心支持go的库少,c语言可以搞定就行了,而且c的数据类型可以很容易的转换成go的数据类型,go也支持指针,支持goto,不久的将来可以在编译器级别支持多核编程。
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"));
System.out.println(jsonObj.get("Id"));
}
catch(IOException e){
System.out.println(e);
}
}
}
go语言可以使用gdb调试,也可以直接嵌套C语言,所以不用担心支持go的库少,c语言可以搞定就行了,而且c的数据类型可以很容易的转换成go的数据类型,go也支持指针,支持goto,不久的将来可以在编译器级别支持多核编程。
有疑问加站长微信联系(非本文作者)