After more than 10 years of development, go language has become the most popular emerging language. At present,go language has become the preferred language in cloud computing, and with the popularity of blockchain in recent years, as the bottom of the development of the language go again hot become the Blockchain technology training field first programming language, IBM's fabic and other heavyweight blockchain projects are developed based on the go language.
As everyone knows, the go language can be developed in many applications. In addition to open source projects such as cloud computing and blockchain, open source projects include DevOps, AI, games, storage engines, WEB, System/command-line tools, middleware, test/continuous delivery, file systems, and more.
A few ways to get the length of a string
-Use bytes. COUNT () statistics
-Use strings. COUNT () statistics
-Convert string to []rune after calling Len function for statistics
-Use UTF8. Runecountinstring () Statistics
Cases:
str:= "Helloword"
L1:=len ([]rune (str))
L2:=bytes. Count ([]byte (str), nil)-1)
L3:=strings. Count (str, "")-1
L4:=utf8. Runecountinstring (str)
Fmt. Println (L1)
Fmt. PRINTLN (L2)
Fmt. Println (L3)
Fmt. Println (L4)
Print Results: all 9
Second, strings. The Count function and the Bytes.count function
The usage of these two functions is the same, just a function on the string, one acting on the byte
The Count method in strings
Func Count (S, Sep string) int{}
Determines the number of occurrences of the character Sep in the string s, returns 1 if it is not found, and returns the length of the string if it is an empty string ("") +1
Cases:
str:= "HelloWorld"
Fmt. PRINTLN (Strings. Count (str, "O"))//print o number of occurrences, printing result is 2
Note: In Golang, if Chinese characters appear in the string, the Len function cannot be called directly to count the string character length, because in Go, the string is stored in UTF-8 format, and the Len function is called on the string to get the number of bytes contained in the string.
str:= "HelloWorld"
STR1: = "Hello, World"
Fmt. Println (Len (STR1))//print Result: 13
Fmt. PRINTLN (len (str))//Print Result: 9 (if it is a string of plain English characters, you can use it to determine the length of the string)
How to call the Golang RPC method across languages
In the three examples above, we implemented the RPC server in Golang using NET/RPC, Net/rpc/jsonrpc, Protorpc, and the corresponding Golang client RPC invocation example, because JSON and PROTOBUF are multi-language supported , so the RPC method implemented with JSONRPC and PROTORPC can be invoked in other languages. The following is a PHP client program that invokes the server-side RPC method implemented by JSONRPC via the socket connection.
$PHPROOT/jsonrpc.php
Class Jsonrpc {
Private $conn;
function __construct ($host, $port) {
$this->conn = Fsockopen ($host, $port, $errno, $ERRSTR, 3);
if (! $this->conn) {
return false;
}
}
Public function call ($method, $params) {
if (! $this->conn) {
return false;
}
$err = fwrite ($this->conn, Json_encode (Array (
' Method ' = $method,
' params ' = = Array ($params),
' id ' = 0,
))." \ n ");
if ($err = = = False) {
return false;
}
Stream_set_timeout ($this->conn, 0, 3000);
$line = fgets ($this->conn);
if ($line = = = False) {
return NULL;
}
Return Json_decode ($line, true);
}
}
$client = new Jsonrpc ("127.0.0.1", 8096);
$args = Array (' A ' =>9, ' B ' =>2);
$r = $client->call ("arith.multiply", $args);
printf ("%d *%d =%d\n", $args [' A '], $args [' B '], $r [' Result '] [' Pro ']);
$r = $client->call ("Arith.divide", Array (' A ' =>9, ' B ' =>2));
printf ("%d/%d, Quo is%d, Rem is%d\n", $args [' A '], $args [' B '], $r [' Result '] [' Quo '], $r [' Result '] [' Rem ']);
Other RPC Libraries
In addition to the above mentioned three ways to implement RPC in the Golang, there are some other RPC library provides similar functionality, more famous Google open source Grpc, but the initial installation of GRPC is troublesome, here is not further introduced, interested can understand.
The above example shows the process of implementing RPC using NET/RPC, but there is no way to invoke the RPC method implemented in the example above in other languages. So the next example is to demonstrate the RPC method implemented using the NET/RPC/JSONRPC library, which supports cross-language invocation.
$GOPATH/src/test/rpc/jsonrpc_server.go
Package Main
Import (
"Errors"
"FMT"
"Log"
"NET"
"Net/rpc"
"Net/rpc/jsonrpc"
"OS"
)
Arithmetic Operation structure Body
Type Arith struct {
}
Arithmetic operation request struct
Type arithrequest struct {
A int
B int
}
Arithmetic Operation response structure body
Type Arithresponse struct {
Pro Int//Product
Quo Int//quotient
Rem Int//remainder
}
Multiplication Operation method
Func (this *arith) Multiply (req arithrequest, res *arithresponse) error {
Res. Pro = req. A * Req. B
return Nil
}
Division Operation method
Func (this *arith) Divide (req arithrequest, res *arithresponse) error {
If req. B = = 0 {
return errors. New ("Divide by Zero")
}
Res. Quo = req. A/req. B
Res. Rem = req. A% req. B
return Nil
}
Func Main () {
Rpc. Register (new (Arith))//Registered RPC service
Lis, Err: = Net. Listen ("TCP", "127.0.0.1:8096")
If err! = Nil {
Log. Fatalln ("Fatal error:", err)
}
Fmt. fprintf (OS. Stdout, "%s", "Start Connection")
for {
Conn, err: = Lis. Accept ()//Receive Client connection request
If err! = Nil {
Continue
}
Go func (Conn net. Conn) {//concurrent processing of client requests
Fmt. fprintf (OS. Stdout, "%s", "New client in coming\n")
Jsonrpc. SERVECONN (conn)
} (conn)
}
}
When the above service-side program starts, it listens to the local 8096 port and processes the client's TCP connection request. We can use Golang to implement a client program to connect to the above service side and make RPC calls.
$GOPATH/src/test/rpc/jsonrpc_client.go
Package Main
Import (
"FMT"
"Log"
"Net/rpc/jsonrpc"
)
Arithmetic operation request struct
Type arithrequest struct {
A int
B int
}
Arithmetic Operation response structure body
Type Arithresponse struct {
Pro Int//Product
Quo Int//quotient
Rem Int//remainder
}
Func Main () {
Conn, err: = Jsonrpc. Dial ("TCP", "127.0.0.1:8096")
If err! = Nil {
Log. Fatalln ("Dailing error:", err)
}
Req: = arithrequest{9, 2}
var res arithresponse
ERR = conn. Call ("Arith.multiply", req, &res)//multiplication
If err! = Nil {
Log. Fatalln ("Arith error:", err)
}
Fmt. Printf ("%d *%d =%d\n", req. A, req. B, Res. Pro)
ERR = conn. Call ("Arith.divide", req, &res)
If err! = Nil {
Log. Fatalln ("Arith error:", err)
}
Fmt. Printf ("%d/%d, quo is%d, REM is%d\n", req. A, req. B, Res. Quo, Res. REM)
}
PROTORPC Library
In order to implement the cross-language invocation, we should choose a cross-language data encoding and decoding method when implementing RPC in Golang, such as JSON, the above JSONRPC can meet this requirement, but there are some shortcomings, such as not support HTTP transmission, data codec performance is not high. So, some third-party RPC libraries have chosen to use PROTOBUF for data encoding and decoding, and provide some service registration code automatic generation function. In the following example we use PROTOBUF to define the RPC method and its request response parameters, and use a third-party PROTORPC library to generate the RPC service registration code.
First, you need to install PROTOBUF and PROTOC executable commands, you can refer to this article: Protobuf Quick Start Guide
We then write a proto file that defines the RPC method to implement and its associated parameters.
$GOPATH/src/test/rpc/pb/arith.proto
Syntax = "Proto3";
Package PB;
Arithmetic operation request Structure
Message Arithrequest {
Int32 a = 1;
Int32 b = 2;
}
Arithmetic Operation response Structure
Message Arithresponse {
Int32 pro = 1; Product
Int32 quo = 2; Business
Int32 rem = 3; Remainder
}
RPC method
Service Arithservice {
RPC Multiply (arithrequest) returns (Arithresponse); Multiplication Operation method
RPC Divide (arithrequest) returns (Arithresponse); Division Operation method
}
Next we need to generate the RPC service code based on the Arith.proto file defined above.
To install the PROTORPC library first: Go get github.com/chai2010/protorpc
Then use the Protoc tool to generate the code: PROTOC--go_out=plugin=protorpc=. Arith.proto
After executing the PROTOC command, a arith.pb.go file is generated in the same directory as the Arith.proto file, which contains the RPC method definition and the code for the Service registration.
Based on the generated Arith.pb.go code, let's implement an RPC server.
$GOPATH/src/test/rpc/protorpc_server.go
Package Main
Import (
"Errors"
"TEST/RPC/PB"
)
Arithmetic Operation structure Body
Type Arith struct {
}
Multiplication Operation method
Func (this *arith) Multiply (req *pb. Arithrequest, Res *PB. Arithresponse) Error {
Res. Pro = req. Geta () * req. GETB ()
return Nil
}
Division Operation method
Func (this *arith) Divide (req *pb. Arithrequest, Res *PB. Arithresponse) Error {
If req. GETB () = = 0 {
return errors. New ("Divide by Zero")
}
Res. Quo = req. Geta ()/req. GETB ()
Res. Rem = req. Geta ()% req. GETB ()
return Nil
}
Func Main () {
Pb. Listenandservearithservice ("TCP", "127.0.0.1:8097", New (Arith))
}
Running the above program will listen to the local 8097 port and receive TCP connections from the client.
Implement a client program based on Ariti.pb.go.
$GOPATH/src/test/protorpc_client.go
Package Main
Import (
"FMT"
"Log"
"TEST/RPC/PB"
)
Func Main () {
Conn, err: = PB. Dialarithservice ("TCP", "127.0.0.1:8097")
If err! = Nil {
Log. Fatalln ("Dailing error:", err)
}
Defer Conn. Close ()
Req: = &PB. Arithrequest{9, 2}
Res, ERR: = conn. Multiply (req)
If err! = Nil {
Log. Fatalln ("Arith error:", err)
}
Fmt. Printf ("%d *%d =%d\n", req. Geta (), req. GETB (), Res. Getpro ())
Res, err = conn. Divide (req)
If err! = Nil {
Log. Fatalln ("Arith error", err)
}
Fmt. Printf ("%d/%d, quo is%d, REM is%d\n", req. A, req. B, Res. Quo, Res. REM)
}
ڡǖ_ '