兄弟連區塊鏈培訓分享Go語言中擷取字串長度的方法

來源:互聯網
上載者:User

  Go語言經過十餘年的發展,已成為最流行的新興語言。目前,Go語言已成為雲端運算領域的慣用語言,且隨著近幾年區塊鏈的流行,作為底層開發語言的Go再次火爆成為區塊鏈技術培訓領域第一程式設計語言,IBM的Fabic等重量級的區塊鏈項目都是基於Go語言開發的。

  殊不知,Go語言可開發的應用項目還有很多。除雲端運算、區塊鏈等開源項目外,還包含Devops、人工智慧、遊戲、儲存引擎、Web、系統/命令列工具、中介軟體、測試/持續傳遞、檔案系統等各方面的開源項目。

一、擷取字串長度的幾種方法

-使用 bytes.Count() 統計

-使用 strings.Count() 統計

-將字串轉換為 []rune 後調用 len 函數進行統計

-使用 utf8.RuneCountInString() 統計

例:

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)


列印結果:都是9


二、strings.Count函數和bytes.Count函數


這兩個函數的用法是相同,只是一個作用在字串上,一個作用在位元組上


strings中的Count方法


func Count(s, sep string) int{}

判斷字元sep在字串s中出現的次數,沒有找到則返回-1,如果為空白字串("")則返回字串的長度+1


例:


str:="HelloWorld"


fmt.Println(strings.Count(str,"o"))  //列印 o 出現的次數,列印結果為2


註:在Golang中,如果字串中出現中文字元不能直接調用 len 函數來統計字串字元長度,這是因為在 Go 中,字串是以 UTF-8 為格式進行儲存的,在字串上調用 len 函數,取得的是字串包含的 byte 的個數。


str:="HelloWorld"


str1 := "Hello,世界"


fmt.Println(len(str1)) //列印結果:13


fmt.Println(len(str)) //列印結果:9 (如果是純英文字元的字串,可以使用來判斷字串的長度)


如何跨語言調用golang的RPC方法

上面的三個例子,我們分別使用net/rpc、net/rpc/jsonrpc、protorpc實現了golang中的RPC服務端,並給出了對應的golang用戶端RPC調用樣本,因為JSON和protobuf是支援多語言的,所以使用jsonrpc和protorpc實現的RPC方法我們是可以在其他語言中進行調用的。下面給出一個php用戶端程式,通過socket串連調用jsonrpc實現的服務端RPC方法。


$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']);

其他RPC庫

除了上面提到的三種在golang實現RPC的方式外,還有一些其他的rpc庫提供了類似的功能,比較出名的有google開源的grpc,但是grpc的初次安裝比較麻煩,這裡就不做進一步介紹了,有興趣的可以自己瞭解。


上面的例子我們示範了使用net/rpc實現RPC的過程,但是沒辦法在其他語言中調用上面例子實現的RPC方法。所以接下來的例子我們示範一下使用net/rpc/jsonrpc庫實現RPC方法,此方式實現的RPC方法支援跨語言調用。


$GOPATH/src/test/rpc/jsonrpc_server.go


package main


import (

    "errors"

    "fmt"

    "log"

    "net"

    "net/rpc"

    "net/rpc/jsonrpc"

    "os"

)


//算數運算結構體

type Arith struct {

}


//算數運算請求結構體

type ArithRequest struct {

    A int

    B int

}


//算數運算響應結構體

type ArithResponse struct {

Pro int //乘積

Quo int //商

Rem int //餘數

}


//乘法運算方法

func (this *Arith) Multiply(req ArithRequest, res *ArithResponse) error {

    res.Pro = req.A * req.B

    return nil

}


//除法運算方法

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)) //註冊rpc服務


    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() //接收用戶端串連請求

        if err != nil {

            continue

        }


go func(conn net.Conn) { //並發處理用戶端請求

            fmt.Fprintf(os.Stdout, "%s", "new client in coming\n")

            jsonrpc.ServeConn(conn)

        }(conn)

    }

}

上述服務端程式啟動後,將會監聽本地的8096連接埠,並處理用戶端的tcp串連請求。我們可以用golang實現一個用戶端程式串連上述服務端並進行RPC調用。


$GOPATH/src/test/rpc/jsonrpc_client.go


package main


import (

    "fmt"

    "log"

    "net/rpc/jsonrpc"

)


//算數運算請求結構體

type ArithRequest struct {

    A int

    B int

}


//算數運算響應結構體

type ArithResponse struct {

Pro int //乘積

Quo int //商

Rem int //餘數

}


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) //乘法運算

    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庫

為了實現跨語言調用,在golang中實現RPC方法的時候我們應該選擇一種跨語言的資料編解碼方式,比如JSON,上述的jsonrpc可以滿足此要求,但是也存在一些缺點,比如不支援http傳輸,資料編解碼效能不高等。於是呢,一些第三方rpc庫都選擇採用protobuf進行資料編解碼,並提供一些服務註冊代碼自動產生功能。下面的例子我們使用protobuf來定義RPC方法及其請求響應參數,並使用第三方的protorpc庫來產生RPC服務註冊代碼。


首先,需要安裝protobuf及protoc可執行命令,可以參考此篇文章:protobuf快速上手指南


然後,我們編寫一個proto檔案,定義要實現的RPC方法及其相關參數。


$GOPATH/src/test/rpc/pb/arith.proto


syntax = "proto3";

package pb;


//算術運算請求結構

message ArithRequest {

    int32 a = 1;

    int32 b = 2;

}


//算術運算響應結構

message ArithResponse {

int32 pro = 1;  //乘積

int32 quo = 2;  //商

int32 rem = 3;  //餘數

}


// rpc方法

service ArithService {

rpc multiply (ArithRequest) returns (ArithResponse);    //乘法運算方法

rpc divide (ArithRequest) returns (ArithResponse);      //除法運算方法

}

接下來我們需要根據上述定義的arith.proto檔案產生RPC服務代碼。

要先安裝protorpc庫:go get github.com/chai2010/protorpc

然後使用protoc工具產生代碼:protoc --go_out=plugin=protorpc=. arith.proto

執行protoc命令後,在與arith.proto檔案同級的目錄下產生了一個arith.pb.go檔案,裡麵包含了RPC方法定義和服務註冊的代碼。


基於產生的arith.pb.go代碼我們來實現一個rpc服務端


$GOPATH/src/test/rpc/protorpc_server.go


package main


import (

    "errors"

    "test/rpc/pb"

)


//算術運算結構體

type Arith struct {

}


//乘法運算方法

func (this *Arith) Multiply(req *pb.ArithRequest, res *pb.ArithResponse) error {

    res.Pro = req.GetA() * req.GetB()

    return nil

}


//除法運算方法

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))

}

運行上述程式,將會監聽本地的8097連接埠並接收用戶端的tcp串連。


基於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)

}

ڡǕ��_'�

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.