golang操作Redis&Mysql&RabbitMQ方法

golang操作Redis&Mysql&RabbitMQ:

Reids

安裝導(dǎo)入

go?get?github.com/garyburd/redigo/redis

import?"github.com/garyburd/redigo/redis"

使用

連接

import?"github.com/garyburd/redigo/redis"

func?main()?{

c,?err?:=?redis.Dial("tcp",?"localhost:6379")

if?err?!=?nil?{

fmt.Println("conn?redis?failed,?err:",?err)

return

}

defer?c.Close()

}

set & get

_,?err?=?c.Do("Set",?"name",?"nick")

if?err?!=?nil?{

fmt.Println(err)

return

}

r,?err?:=?redis.String(c.Do("Get",?"name"))

if?err?!=?nil?{

fmt.Println(err)

return

}

fmt.Println(r)

mset & mget

批量設(shè)置

_,?err?=?c.Do("MSet",?"name",?"nick",?"age",?"18")

if?err?!=?nil?{

fmt.Println("MSet?error:?",?err)

return

}

r2,?err?:=?redis.Strings(c.Do("MGet",?"name",?"age"))

if?err?!=?nil?{

fmt.Println("MGet?error:?",?err)

return

}

fmt.Println(r2)

hset & hget

hash操作

_,?err?=?c.Do("HSet",?"names",?"nick",?"suoning")

if?err?!=?nil?{

fmt.Println("hset?error:?",?err)

return

}

r,?err?=?redis.String(c.Do("HGet",?"names",?"nick"))

if?err?!=?nil?{

fmt.Println("hget?error:?",?err)

return

}

fmt.Println(r)

expire

設(shè)置過期時間

_,?err?=?c.Do("expire",?"names",?5)

if?err?!=?nil?{

fmt.Println("expire?error:?",?err)

return

}

lpush & lpop & llen

隊列

//?隊列

_,?err?=?c.Do("lpush",?"Queue",?"nick",?"dawn",?9)

if?err?!=?nil?{

fmt.Println("lpush?error:?",?err)

return

}

for?{

r,?err?=?redis.String(c.Do("lpop",?"Queue"))

if?err?!=?nil?{

fmt.Println("lpop?error:?",?err)

break

}

fmt.Println(r)

}

r3,?err?:=?redis.Int(c.Do("llen",?"Queue"))

if?err?!=?nil?{

fmt.Println("llen?error:?",?err)

return

}

連接池

各參數(shù)的解釋如下:

MaxIdle:最大的空閑連接數(shù),表示即使沒有redis連接時依然可以保持N個空閑的連接,而不被清除,隨時處于待命狀態(tài)酌心。

MaxActive:最大的激活連接數(shù),表示同時最多有N個連接

IdleTimeout:最大的空閑連接等待時間逸绎,超過此時間后饮笛,空閑連接將被關(guān)閉

pool?:=?&redis.Pool{

MaxIdle:?????16,

MaxActive:???1024,

IdleTimeout:?300,

Dial:?func()?(redis.Conn,?error)?{

return?redis.Dial("tcp",?"localhost:6379")

},

}

連接池例子:

package?main

import?(

"fmt"

"github.com/garyburd/redigo/redis"

)

var?pool?*redis.Pool

func?init()?{

pool?=?&redis.Pool{

MaxIdle:?????16,

MaxActive:???1024,

IdleTimeout:?300,

Dial:?func()?(redis.Conn,?error)?{

return?redis.Dial("tcp",?"localhost:6379")

},

}

}

func?main()?{

c?:=?pool.Get()

defer?c.Close()

_,?err?:=?c.Do("Set",?"name",?"nick")

if?err?!=?nil?{

fmt.Println(err)

return

}

r,?err?:=?redis.String(c.Do("Get",?"name"))

if?err?!=?nil?{

fmt.Println(err)

return

}

fmt.Println(r)

}

管道操作

請求/響應(yīng)服務(wù)可以實現(xiàn)持續(xù)處理新請求蹄梢,客戶端可以發(fā)送多個命令到服務(wù)器而無需等待響應(yīng)稽亏,最后在一次讀取多個響應(yīng)壶冒。

使用Send(),F(xiàn)lush()截歉,Receive()方法支持管道化操作

Send向連接的輸出緩沖中寫入命令胖腾。

Flush將連接的輸出緩沖清空并寫入服務(wù)器端。

Recevie按照FIFO順序依次讀取服務(wù)器的響應(yīng)瘪松。

func?main()?{

c,?err?:=?redis.Dial("tcp",?"localhost:6379")

if?err?!=?nil?{

fmt.Println("conn?redis?failed,?err:",?err)

return

}

defer?c.Close()

c.Send("SET",?"name1",?"sss1")

c.Send("SET",?"name2",?"sss2")

c.Flush()

v,?err?:=?c.Receive()

fmt.Printf("v:%v,err:%v\n",?v,?err)

v,?err?=?c.Receive()

fmt.Printf("v:%v,err:%v\n",?v,?err)

v,?err?=?c.Receive()????//?夯住咸作,一直等待

fmt.Printf("v:%v,err:%v\n",?v,?err)

}

Mysql

安裝導(dǎo)入

go?get?"github.com/go-sql-driver/mysql"

go?get?"github.com/jmoiron/sqlx"

import?(

_?"github.com/go-sql-driver/mysql"

"github.com/jmoiron/sqlx"

)

連接

import?(

_?"github.com/go-sql-driver/mysql"

"github.com/jmoiron/sqlx"

)

var?Db?*sqlx.DB

func?init()?{

database,?err?:=?sqlx.Open("mysql",?"root:@tcp(127.0.0.1:3306)/test")

if?err?!=?nil?{

fmt.Println("open?mysql?failed,",?err)

return

}

Db?=?database

}

建表

CREATE?TABLE?`person`?(

`user_id`?int(128)?DEFAULT?NULL,

`username`?varchar(255)?DEFAULT?NULL,

`sex`?varchar(16)?DEFAULT?NULL,

`email`?varchar(128)?DEFAULT?NULL

)?ENGINE=InnoDB?DEFAULT?CHARSET=utf8

(insert)

package?main

import?(

"fmt"

_?"github.com/go-sql-driver/mysql"

"github.com/jmoiron/sqlx"

)

type?Person?struct?{

UserId???int????`db:"user_id"`

Username?string?`db:"username"`

Sex??????string?`db:"sex"`

Email????string?`db:"email"`

}

var?Db?*sqlx.DB

func?init()?{

database,?err?:=?sqlx.Open("mysql",?"root:@tcp(127.0.0.1:3306)/test")

if?err?!=?nil?{

fmt.Println("open?mysql?failed,",?err)

return

}

Db?=?database

}

func?main()?{

r,?err?:=?Db.Exec("insert?into?person(username,?sex,?email)values(?,??,??)",?"suoning",?"man",?"suoning@net263.com")

if?err?!=?nil?{

fmt.Println("exec?failed,?",?err)

return

}

id,?err?:=?r.LastInsertId()

if?err?!=?nil?{

fmt.Println("exec?failed,?",?err)

return

}

fmt.Println("insert?succ:",?id)

}

(update)

package?main

import?(

"fmt"

_?"github.com/go-sql-driver/mysql"

"github.com/jmoiron/sqlx"

)

type?Person?struct?{

UserId???int????`db:"user_id"`

Username?string?`db:"username"`

Sex??????string?`db:"sex"`

Email????string?`db:"email"`

}

var?Db?*sqlx.DB

func?init()?{

database,?err?:=?sqlx.Open("mysql",?"root:@tcp(127.0.0.1:3306)/test")

if?err?!=?nil?{

fmt.Println("open?mysql?failed,",?err)

return

}

Db?=?database

}

func?main()?{

_,?err?:=?Db.Exec("update?person?set?user_id=??where?username=?",?20170808,?"suoning")

if?err?!=?nil?{

fmt.Println("exec?failed,?",?err)

return

}

}

(select)

package?main

import?(

"fmt"

_?"github.com/go-sql-driver/mysql"

"github.com/jmoiron/sqlx"

)

type?Person?struct?{

UserId???int????`db:"user_id"`

Username?string?`db:"username"`

Sex??????string?`db:"sex"`

Email????string?`db:"email"`

}

type?Place?struct?{

Country?string?`db:"country"`

City????string?`db:"city"`

TelCode?int????`db:"telcode"`

}

var?Db?*sqlx.DB

func?init()?{

database,?err?:=?sqlx.Open("mysql",?"root:@tcp(127.0.0.1:3306)/test")

if?err?!=?nil?{

fmt.Println("open?mysql?failed,",?err)

return

}

Db?=?database

}

func?main()?{

var?person?[]Person

err?:=?Db.Select(&person,?"select?user_id,?username,?sex,?email?from?person?where?user_id=?",?1)

if?err?!=?nil?{

fmt.Println("exec?failed,?",?err)

return

}

fmt.Println("select?succ:",?person)

people?:=?[]Person{}

Db.Select(&people,?"SELECT?*?FROM?person?ORDER?BY?user_id?ASC")

fmt.Println(people)

jason,?john?:=?people[0],?people[1]

fmt.Printf("%#v\n%#v",?jason,?john)

}

(delete)

package?main

import?(

"fmt"

_?"github.com/go-sql-driver/mysql"

"github.com/jmoiron/sqlx"

)

type?Person?struct?{

UserId???int????`db:"user_id"`

Username?string?`db:"username"`

Sex??????string?`db:"sex"`

Email????string?`db:"email"`

}

var?Db?*sqlx.DB

func?init()?{

database,?err?:=?sqlx.Open("mysql",?"root:@tcp(127.0.0.1:3306)/test")

if?err?!=?nil?{

fmt.Println("open?mysql?failed,",?err)

return

}

Db?=?database

}

func?main()?{

_,?err?:=?Db.Exec("delete?from?person?where?username=??limit?1",?"suoning")

if?err?!=?nil?{

fmt.Println("exec?failed,?",?err)

return

}

fmt.Println("delete?succ")

}

事務(wù)

package?main

import?(

"github.com/astaxie/beego/logs"

_?"github.com/go-sql-driver/mysql"

"github.com/jmoiron/sqlx"

)

var?Db?*sqlx.DB

func?init()?{

database,?err?:=?sqlx.Open("mysql",?"root:@tcp(127.0.0.1:3306)/test")

if?err?!=?nil?{

logs.Error("open?mysql?failed,",?err)

return

}

Db?=?database

}

func?main()??{

conn,?err?:=?Db.Begin()

if?err?!=?nil?{

logs.Warn("DB.Begin?failed,?err:%v",?err)

return

}

defer?func()?{

if?err?!=?nil?{

conn.Rollback()

return

}

conn.Commit()

}()

//?do?something

}

RabbitMQ

安裝

go?get?"github.com/streadway/amqp"

普通模式

生產(chǎn)者:

package?main

import?(????"fmt"

"log"

"os"

"strings"

"github.com/streadway/amqp"

"time")/*默認(rèn)點對點模式*/func?failOnError(err?error,?msg?string)?{????if?err?!=?nil?{

log.Fatalf("%s:?%s",?msg,?err)

panic(fmt.Sprintf("%s:?%s",?msg,?err))

}

}

func?main()?{????//?連接

conn,?err?:=?amqp.Dial("amqp://guest:guest@localhost:5672/")

failOnError(err,?"Failed?to?connect?to?RabbitMQ")

defer?conn.Close()????//?打開一個并發(fā)服務(wù)器通道來處理消息

ch,?err?:=?conn.Channel()

failOnError(err,?"Failed?to?open?a?channel")

defer?ch.Close()????//?申明一個隊列

q,?err?:=?ch.QueueDeclare(????????"task_queue",?//?name

true,?????????//?durable??持久性的,如果事前已經(jīng)聲明了該隊列,不能重復(fù)聲明

false,????????//?delete?when?unused

false,????????//?exclusive?如果是真宵睦,連接一斷開记罚,隊列刪除

false,????????//?no-wait

nil,??????????//?arguments????)

failOnError(err,?"Failed?to?declare?a?queue")

body?:=?bodyFrom(os.Args)????//?發(fā)布

err?=?ch.Publish(????????"",?????//?exchange?默認(rèn)模式,exchange為空

q.Name,???????????//?routing?key?默認(rèn)模式路由到同名隊列壳嚎,即是task_queue

false,??//?mandatory

false,

amqp.Publishing{????????????//?持久性的發(fā)布桐智,因為隊列被聲明為持久的末早,發(fā)布消息必須加上這個(可能不用),但消息還是可能會丟酵使,如消息到緩存但MQ掛了來不及持久化荐吉。????????????DeliveryMode:?amqp.Persistent,

ContentType:??"text/plain",

Body:?????????[]byte(body),

})

failOnError(err,?"Failed?to?publish?a?message")

log.Printf("?[x]?Sent?%s",?body)

}

func?bodyFrom(args?[]string)?string?{????var?s?string

if?(len(args)?<?2)?||?os.Args[1]?==?""?{

s?=?fmt.Sprintf("%s-%v","hello",?time.Now())

}?else?{

s?=?strings.Join(args[1:],?"?")

}????return?s

}

消費者:

package?main

import?(

"bytes"

"fmt"

"github.com/streadway/amqp"

"log"

"time"

)

/*

默認(rèn)點對點模式

工作方焙糟,多個嫡秕,拿發(fā)布方的消息

*/

func?failOnError(err?error,?msg?string)?{

if?err?!=?nil?{

log.Fatalf("%s:?%s",?msg,?err)

panic(fmt.Sprintf("%s:?%s",?msg,?err))

}

}

func?main()?{

conn,?err?:=?amqp.Dial("amqp://guest:guest@localhost:5672/")

failOnError(err,?"Failed?to?connect?to?RabbitMQ")

defer?conn.Close()

ch,?err?:=?conn.Channel()

failOnError(err,?"Failed?to?open?a?channel")

defer?ch.Close()

//?指定隊列岸浑!

q,?err?:=?ch.QueueDeclare(

"task_queue",?//?name

true,?????????//?durable

false,????????//?delete?when?unused

false,????????//?exclusive

false,????????//?no-wait

nil,??????????//?arguments

)

failOnError(err,?"Failed?to?declare?a?queue")

//?Fair?dispatch?預(yù)取,每個工作方每次拿一個消息,確認(rèn)后才拿下一次郊闯,緩解壓力

err?=?ch.Qos(

1,?????//?prefetch?count

0,?????//?prefetch?size

false,?//?global

)

failOnError(err,?"Failed?to?set?QoS")

//?消費根據(jù)隊列名

msgs,?err?:=?ch.Consume(

q.Name,?//?queue

"",?????//?consumer

false,??//?auto-ack???設(shè)置為真自動確認(rèn)消息

false,??//?exclusive

false,??//?no-local

false,??//?no-wait

nil,????//?args

)

failOnError(err,?"Failed?to?register?a?consumer")

forever?:=?make(chan?bool)

go?func()?{

for?d?:=?range?msgs?{

log.Printf("Received?a?message:?%s",?d.Body)

dot_count?:=?bytes.Count(d.Body,?[]byte("."))

t?:=?time.Duration(dot_count)

time.Sleep(t?*?time.Second)

log.Printf("Done")

//?確認(rèn)消息被收到!羹膳!如果為真的胖齐,那么同在一個channel,在該消息之前未確認(rèn)的消息都會確認(rèn),適合批量處理

//?真時場景:每十條消息確認(rèn)一次栗柒,類似

d.Ack(false)

}

}()

log.Printf("?[*]?Waiting?for?messages.?To?exit?press?CTRL+C")

<-forever

}

訂閱模式

訂閱 生產(chǎn)者:

package?main

import?(

"fmt"

"github.com/streadway/amqp"

"log"

"os"

"strings"

"time"

)

/*

廣播模式

發(fā)布方

*/

func?failOnError(err?error,?msg?string)?{

if?err?!=?nil?{

log.Fatalf("%s:?%s",?msg,?err)

panic(fmt.Sprintf("%s:?%s",?msg,?err))

}

}

func?main()?{

conn,?err?:=?amqp.Dial("amqp://guest:guest@localhost:5672/")

failOnError(err,?"Failed?to?connect?to?RabbitMQ")

defer?conn.Close()

ch,?err?:=?conn.Channel()

failOnError(err,?"Failed?to?open?a?channel")

defer?ch.Close()

//?默認(rèn)模式有默認(rèn)交換機礁扮,廣播自己定義一個交換機,交換機可與隊列進行綁定

err?=?ch.ExchangeDeclare(

"logs",???//?name

"fanout",?//?type?廣播模式

true,?????//?durable

false,????//?auto-deleted

false,????//?internal

false,????//?no-wait

nil,??????//?arguments

)

failOnError(err,?"Failed?to?declare?an?exchange")

body?:=?bodyFrom(os.Args)

//?發(fā)布

err?=?ch.Publish(

"logs",?//?exchange?消息發(fā)送到交換機瞬沦,這個時候沒隊列綁定交換機太伊,消息會丟棄

"",?????//?routing?key??廣播模式不需要這個,它會把所有消息路由到綁定的所有隊列

false,??//?mandatory

false,??//?immediate

amqp.Publishing{

ContentType:?"text/plain",

Body:????????[]byte(body),

})

failOnError(err,?"Failed?to?publish?a?message")

log.Printf("?[x]?Sent?%s",?body)

}

func?bodyFrom(args?[]string)?string?{

var?s?string

if?(len(args)?<?2)?||?os.Args[1]?==?""?{

s?=?fmt.Sprintf("%s-%v","hello",?time.Now())

}?else?{

s?=?strings.Join(args[1:],?"?")

}

return?s

}

訂閱 消費者:

package?main

import?(

"fmt"

"github.com/streadway/amqp"

"log"

)

/*

廣播模式

訂閱方

*/

func?failOnError(err?error,?msg?string)?{

if?err?!=?nil?{

log.Fatalf("%s:?%s",?msg,?err)

panic(fmt.Sprintf("%s:?%s",?msg,?err))

}

}

func?main()?{

conn,?err?:=?amqp.Dial("amqp://guest:guest@localhost:5672/")

failOnError(err,?"Failed?to?connect?to?RabbitMQ")

defer?conn.Close()

ch,?err?:=?conn.Channel()

failOnError(err,?"Failed?to?open?a?channel")

defer?ch.Close()

//?同樣要申明交換機

err?=?ch.ExchangeDeclare(

"logs",???//?name

"fanout",?//?type

true,?????//?durable

false,????//?auto-deleted

false,????//?internal

false,????//?no-wait

nil,??????//?arguments

)

failOnError(err,?"Failed?to?declare?an?exchange")

//?新建隊列逛钻,這個隊列沒名字僚焦,隨機生成一個名字

q,?err?:=?ch.QueueDeclare(

"",????//?name

false,?//?durable

false,?//?delete?when?usused

true,??//?exclusive??表示連接一斷開,這個隊列自動刪除

false,?//?no-wait

nil,???//?arguments

)

failOnError(err,?"Failed?to?declare?a?queue")

//?隊列和交換機綁定曙痘,即是隊列訂閱了發(fā)到這個交換機的消息

err?=?ch.QueueBind(

q.Name,?//?queue?name??隊列的名字

"",?????//?routing?key??廣播模式不需要這個

"logs",?//?exchange??交換機名字

false,

nil)

failOnError(err,?"Failed?to?bind?a?queue")

//?開始消費消息芳悲,可開多個訂閱方,因為隊列是臨時生成的边坤,所有每個訂閱方都能收到同樣的消息

msgs,?err?:=?ch.Consume(

q.Name,?//?queue??隊列名字

"",?????//?consumer

true,???//?auto-ack??自動確認(rèn)

false,??//?exclusive

false,??//?no-local

false,??//?no-wait

nil,????//?args

)

failOnError(err,?"Failed?to?register?a?consumer")

forever?:=?make(chan?bool)

go?func()?{

for?d?:=?range?msgs?{

log.Printf("?[x]?%s",?d.Body)

}

}()

log.Printf("?[*]?Waiting?for?logs.?To?exit?press?CTRL+C")

<-forever

}

RPC模式

RPC 應(yīng)答方:

package?main

import?(

"fmt"

"log"

"strconv"

"github.com/streadway/amqp"

)

/*

RPC模式

應(yīng)答方

*/

func?failOnError(err?error,?msg?string)?{

if?err?!=?nil?{

log.Fatalf("%s:?%s",?msg,?err)

panic(fmt.Sprintf("%s:?%s",?msg,?err))

}

}

func?fib(n?int)?int?{

if?n?==?0?{

return?0

}?else?if?n?==?1?{

return?1

}?else?{

return?fib(n-1)?+?fib(n-2)

}

}

func?main()?{

conn,?err?:=?amqp.Dial("amqp://guest:guest@localhost:5672/")

failOnError(err,?"Failed?to?connect?to?RabbitMQ")

defer?conn.Close()

ch,?err?:=?conn.Channel()

failOnError(err,?"Failed?to?open?a?channel")

defer?ch.Close()

q,?err?:=?ch.QueueDeclare(

"rpc_queue",?//?name

false,???????//?durable

false,???????//?delete?when?usused

false,???????//?exclusive

false,???????//?no-wait

nil,?????????//?arguments

)

failOnError(err,?"Failed?to?declare?a?queue")

//?公平分發(fā)?沒有這個則round-robbin

err?=?ch.Qos(

1,?????//?prefetch?count

0,?????//?prefetch?size

false,?//?global

)

failOnError(err,?"Failed?to?set?QoS")

//?消費名扛,等待請求

msgs,?err?:=?ch.Consume(

q.Name,?//?queue

"",?????//?consumer

false,??//?auto-ack

false,??//?exclusive

false,??//?no-local

false,??//?no-wait

nil,????//?args

)

failOnError(err,?"Failed?to?register?a?consumer")

forever?:=?make(chan?bool)

go?func()?{

//請求來了

for?d?:=?range?msgs?{

n,?err?:=?strconv.Atoi(string(d.Body))

failOnError(err,?"Failed?to?convert?body?to?integer")

log.Printf("?[.]?fib(%d)",?n)

//?計算

response?:=?fib(n)

//?回答

err?=?ch.Publish(

"",????????//?exchange

d.ReplyTo,?//?routing?key

false,?????//?mandatory

false,?????//?immediate

amqp.Publishing{

ContentType:???"text/plain",

CorrelationId:?d.CorrelationId,??//序列號

Body:??????????[]byte(strconv.Itoa(response)),

})

failOnError(err,?"Failed?to?publish?a?message")

//?確認(rèn)回答完畢

d.Ack(false)

}

}()

log.Printf("?[*]?Awaiting?RPC?requests")

<-forever

}

RPC 請求方:

package?main

import?(

"fmt"

"log"

"math/rand"

"os"

"strconv"

"strings"

"time"

"github.com/streadway/amqp"

)

/*

RPC模式

請求方

*/

func?failOnError(err?error,?msg?string)?{

if?err?!=?nil?{

log.Fatalf("%s:?%s",?msg,?err)

panic(fmt.Sprintf("%s:?%s",?msg,?err))

}

}

func?randomString(l?int)?string?{

bytes?:=?make([]byte,?l)

for?i?:=?0;?i?<?l;?i++?{

bytes[i]?=?byte(randInt(65,?90))

}

return?string(bytes)

}

func?randInt(min?int,?max?int)?int?{

return?min?+?rand.Intn(max-min)

}

func?fibonacciRPC(n?int)?(res?int,?err?error)?{

conn,?err?:=?amqp.Dial("amqp://guest:guest@localhost:5672/")

failOnError(err,?"Failed?to?connect?to?RabbitMQ")

defer?conn.Close()

ch,?err?:=?conn.Channel()

failOnError(err,?"Failed?to?open?a?channel")

defer?ch.Close()

//?隊列聲明

q,?err?:=?ch.QueueDeclare(

"",????//?name

false,?//?durable

false,?//?delete?when?usused

true,??//?exclusive?為真即連接斷開就刪除

false,?//?noWait

nil,???//?arguments

)

failOnError(err,?"Failed?to?declare?a?queue")

msgs,?err?:=?ch.Consume(

q.Name,?//?queue

"",?????//?consumer

true,???//?auto-ack

false,??//?exclusive???這個為真,服務(wù)器會認(rèn)為這是該隊列唯一的消費者

false,??//?no-local

false,??//?no-wait

nil,????//?args

)

failOnError(err,?"Failed?to?register?a?consumer")

corrId?:=?randomString(32)

err?=?ch.Publish(

"",??????????//?exchange

"rpc_queue",?//?routing?key

false,???????//?mandatory

false,???????//?immediate

amqp.Publishing{

ContentType:???"text/plain",

CorrelationId:?corrId,

ReplyTo:???????q.Name,

Body:??????????[]byte(strconv.Itoa(n)),

})

failOnError(err,?"Failed?to?publish?a?message")

for?d?:=?range?msgs?{

if?corrId?==?d.CorrelationId?{

res,?err?=?strconv.Atoi(string(d.Body))

failOnError(err,?"Failed?to?convert?body?to?integer")

break

}

}

return

}

func?main()?{

rand.Seed(time.Now().UTC().UnixNano())

n?:=?bodyFrom(os.Args)

log.Printf("?[x]?Requesting?fib(%d)",?n)

res,?err?:=?fibonacciRPC(n)

failOnError(err,?"Failed?to?handle?RPC?request")

log.Printf("?[.]?Got?%d",?res)

}

func?bodyFrom(args?[]string)?int?{

var?s?string

if?(len(args)?<?2)?||?os.Args[1]?==?""?{

s?=?"30"

}?else?{

s?=?strings.Join(args[1:],?"?")

}

n,?err?:=?strconv.Atoi(s)

failOnError(err,?"Failed?to?convert?arg?to?integer")

return?n

}

本文來自php中文網(wǎng)的golang欄目:https://www.php.cn/be/go/

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末茧痒,一起剝皮案震驚了整個濱河市罢洲,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌文黎,老刑警劉巖惹苗,帶你破解...
    沈念sama閱讀 210,914評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異耸峭,居然都是意外死亡桩蓉,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評論 2 383
  • 文/潘曉璐 我一進店門劳闹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來院究,“玉大人洽瞬,你說我怎么就攤上這事∫堤” “怎么了伙窃?”我有些...
    開封第一講書人閱讀 156,531評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長样漆。 經(jīng)常有香客問我为障,道長,這世上最難降的妖魔是什么放祟? 我笑而不...
    開封第一講書人閱讀 56,309評論 1 282
  • 正文 為了忘掉前任鳍怨,我火速辦了婚禮,結(jié)果婚禮上跪妥,老公的妹妹穿的比我還像新娘鞋喇。我一直安慰自己,他們只是感情好眉撵,可當(dāng)我...
    茶點故事閱讀 65,381評論 5 384
  • 文/花漫 我一把揭開白布侦香。 她就那樣靜靜地躺著,像睡著了一般纽疟。 火紅的嫁衣襯著肌膚如雪罐韩。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,730評論 1 289
  • 那天仰挣,我揣著相機與錄音伴逸,去河邊找鬼。 笑死膘壶,一個胖子當(dāng)著我的面吹牛错蝴,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播颓芭,決...
    沈念sama閱讀 38,882評論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼顷锰,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了亡问?” 一聲冷哼從身側(cè)響起官紫,我...
    開封第一講書人閱讀 37,643評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎州藕,沒想到半個月后束世,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,095評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡床玻,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,448評論 2 325
  • 正文 我和宋清朗相戀三年毁涉,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片锈死。...
    茶點故事閱讀 38,566評論 1 339
  • 序言:一個原本活蹦亂跳的男人離奇死亡贫堰,死狀恐怖穆壕,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情其屏,我是刑警寧澤喇勋,帶...
    沈念sama閱讀 34,253評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站偎行,受9級特大地震影響川背,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜睦优,卻給世界環(huán)境...
    茶點故事閱讀 39,829評論 3 312
  • 文/蒙蒙 一渗常、第九天 我趴在偏房一處隱蔽的房頂上張望壮不。 院中可真熱鬧汗盘,春花似錦、人聲如沸询一。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,715評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽健蕊。三九已至菱阵,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間缩功,已是汗流浹背晴及。 一陣腳步聲響...
    開封第一講書人閱讀 31,945評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留嫡锌,地道東北人虑稼。 一個月前我還...
    沈念sama閱讀 46,248評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像势木,于是被迫代替她去往敵國和親蛛倦。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,440評論 2 348

推薦閱讀更多精彩內(nèi)容