Go 璇█涓悓鏃舵湁鍑芥暟鍜屾柟娉曘?span style="color: #ff0000;">鏂規硶灝辨槸涓涓寘鍚簡鎺ュ彈鑰咃紙receiver錛夌殑鍑芥暟錛宺eceiver鍙互鏄唴緗被鍨嬫垨鑰呯粨鏋勪綋綾誨瀷鐨勪竴涓兼垨鑰呮槸涓涓寚閽堛傛墍鏈夌粰瀹氱被鍨嬬殑鏂規硶灞炰簬璇ョ被鍨嬬殑鏂規硶闆嗐?br />
濡備笅闈㈢殑榪欎釜渚嬪瓙錛屽畾涔変簡涓涓柊綾誨瀷Integer錛屽畠鍜宨nt涓鏍鳳紝鍙槸涓哄畠鍐呯疆鐨刬nt綾誨瀷澧炲姞浜嗕釜鏂版柟娉昄ess()
type Integer int func (a Integer) Less(b Integer) bool { return a < b } func main() { var a Integer = 1 if a.Less(2) { fmt.Println("less then 2") } }
鍙互鐪嬪嚭錛孏o璇█鍦ㄨ嚜瀹氫箟綾誨瀷鐨勫璞′腑娌℃湁C++/Java閭g闅愯棌鐨則his鎸囬拡錛岃屾槸鍦ㄥ畾涔夋垚鍛樻柟娉曟椂鏄懼紡澹版槑浜嗗叾鎵灞炵殑瀵硅薄銆?/p>
method鐨勮娉曞涓嬶細
func (r ReceiverType) funcName(parameters) (results)
褰撹皟鐢╩ethod鏃訛紝浼氬皢receiver浣滀負鍑芥暟鐨勭涓涓弬鏁幫細
funcName(r, parameters);
鎵浠ワ紝receiver鏄肩被鍨嬭繕鏄寚閽堢被鍨嬭鐪媘ethod鐨勪綔鐢ㄣ傚鏋滆淇敼瀵硅薄鐨勫鹼紝灝遍渶瑕佷紶閫掑璞$殑鎸囬拡銆?/p>
鎸囬拡浣滀負Receiver浼氬瀹炰緥瀵硅薄鐨勫唴瀹瑰彂鐢熸搷浣?鑰屾櫘閫氱被鍨嬩綔涓篟eceiver浠呬粎鏄互鍓湰浣滀負鎿嶄綔瀵硅薄,騫朵笉瀵瑰師瀹炰緥瀵硅薄鍙戠敓鎿嶄綔銆?/p>
func (a *Ingeger) Add(b Integer) { *a += b } func main() { var a Integer = 1 a.Add(3) fmt.Println("a =", a) // a = 4 }
濡傛灉Add鏂規硶涓嶄嬌鐢ㄦ寚閽堬紝鍒檃榪斿洖鐨勭粨鏋滀笉鍙橈紝榪欐槸鍥犱負Go璇█鍑芥暟鐨勫弬鏁頒篃鏄熀浜庡間紶閫掋?/p>
娉ㄦ剰錛?span style="color: #ff0000;">褰撴柟娉曠殑鎺ュ彈鑰呮槸鎸囬拡鏃訛紝鍗充嬌鐢ㄥ肩被鍨嬭皟鐢ㄩ偅涔堟柟娉曞唴閮ㄤ篃鏄鎸囬拡鐨勬搷浣溿?/span>
涔嬪墠璇磋繃錛孏o璇█娌℃湁鏋勯犲嚱鏁扮殑姒傚康錛岄氬父浣跨敤涓涓叏灞鍑芥暟鏉ュ畬鎴愩備緥濡傦細
func NewRect(x, y, width, height float64) *Rect { return &Rect{x, y, width, height} } func main() { rect1 := NewRect(1,2,10,20) fmt.Println(rect1.width) }
Go璇█鎻愪緵浜嗙戶鎵匡紝浣嗘槸閲囩敤浜嗙粍鍚堢殑璇硶錛屾垜浠皢鍏剁О涓哄尶鍚嶇粍鍚堬紝渚嬪錛?/span>
type Base struct { name string } func (base *Base) Set(myname string) { base.name = myname } func (base *Base) Get() string { return base.name } type Derived struct { Base age int } func (derived *Derived) Get() (nm string, ag int) { return derived.name, derived.age } func main() { b := &Derived{} b.Set("sina") fmt.Println(b.Get()) }
渚嬪瓙涓紝鍦˙ase綾誨瀷瀹氫箟浜唃et()鍜宻et()涓や釜鏂規硶錛岃孌erived綾誨瀷緇ф壙浜咮ase綾伙紝騫舵敼鍐欎簡Get()鏂規硶錛屽湪Derived瀵硅薄璋冪敤Set()鏂規硶錛屼細鍔犺澆鍩虹被瀵瑰簲鐨勬柟娉曪紱鑰岃皟鐢℅et()鏂規硶鏃訛紝鍔犺澆媧劇敓綾繪敼鍐欑殑鏂規硶銆?/p>
緇勫悎鐨勭被鍨嬪拰琚粍鍚堢殑綾誨瀷鍖呭惈鍚屽悕鎴愬憳鏃訛紝 浼氫笉浼氭湁闂鍛紵鍙互鍙傝冧笅闈㈢殑渚嬪瓙錛?/p>
type Base struct { name string age int } func (base *Base) Set(myname string, myage int) { base.name = myname base.age = myage } type Derived struct { Base name string } func main() { b := &Derived{} b.Set("sina", 30) fmt.Println("b.name =",b.name, "\tb.Base.name =", b.Base.name) fmt.Println("b.age =",b.age, "\tb.Base.age =", b.Base.age) }
鍊艱涔夊拰寮曠敤璇箟鐨勫樊鍒湪浜庤祴鍊鹼紝姣斿
b = a b.Modify()
濡傛灉b鐨勪慨鏀逛笉浼氬獎鍝峚鐨勫鹼紝閭d箞姝ょ被鍨嬪睘浜庡肩被鍨嬶紱濡傛灉浼氬獎鍝峚鐨勫鹼紝閭d箞姝ょ被鍨嬫槸寮曠敤綾誨瀷銆?/span>
Go璇█涓殑澶у鏁扮被鍨嬮兘鍩轟簬鍊艱涔夛紝鍖呮嫭錛?/p>
C璇█涓殑鏁扮粍姣旇緝鐗瑰埆錛岄氳繃鍑芥暟浼犻掍竴涓暟緇勭殑鏃跺欏熀浜庡紩鐢ㄨ涔夛紝浣嗘槸鍦ㄧ粨鏋勪綋瀹氫箟鏁扮粍鍙橀噺鐨勬椂鍊欏熀浜庡艱涔夈傝屽湪Go璇█涓紝鏁扮粍鍜屽熀鏈被鍨嬫病鏈夊尯鍒紝鏄緢綰補鐨勫肩被鍨嬶紝渚嬪錛?/p>
var a = [3] int{1,2,3} var b = a b[1]++ fmt.Println(a, b) // [1 2 3] [1 3 3]
浠庣粨鏋滅湅錛宐=a璧嬪艱鍙ユ槸鏁扮粍鍐呭鐨勫畬鏁村鍒訛紝瑕佹兂琛ㄨ揪寮曠敤錛岄渶瑕佺敤鎸囬拡錛?/p>
var a = [3] int{1,2,3} var b = &a銆銆銆銆// 寮曠敤璇箟 b[1]++ fmt.Println(a, b) // [1 3 3] [1 3 3]
Interface 鏄竴緇勬娊璞℃柟娉曪紙鏈叿浣撳疄鐜扮殑鏂規硶/浠呭寘鍚柟娉曞悕鍙傛暟榪斿洖鍊肩殑鏂規硶錛夌殑闆嗗悎錛屽鏋滃疄鐜頒簡 interface 涓殑鎵鏈夋柟娉曪紝鍗寵綾?瀵硅薄灝卞疄鐜頒簡璇ユ帴鍙c?/p>
Interface 鐨勫0鏄庢牸寮忥細
type interfaceName interface { //鏂規硶鍒楄〃 }
Interface 鍙互琚換鎰忓璞″疄鐜幫紝涓涓被鍨?瀵硅薄涔熷彲浠ュ疄鐜板涓?interface錛?br />interface鐨勫彉閲忓彲浠ユ寔鏈変換鎰忓疄鐜拌interface綾誨瀷鐨勫璞°?/span>
濡備笅闈㈢殑渚嬪瓙錛?/p>
package main import "fmt" type Human struct { name string age int phone string } type Student struct { Human //鍖垮悕瀛楁 school string loan float32 } type Employee struct { Human //鍖垮悕瀛楁 company string money float32 } //Human瀹炵幇SayHi鏂規硶 func (h Human) SayHi() { fmt.Printf("Hi, I am %s you can call me on %s\n", h.name, h.phone) } //Human瀹炵幇Sing鏂規硶 func (h Human) Sing(lyrics string) { fmt.Println("La la la la...", lyrics) } //Employee閲嶈澆Human鐨凷ayHi鏂規硶 func (e Employee) SayHi() { fmt.Printf("Hi, I am %s, I work at %s. Call me on %s\n", e.name, e.company, e.phone) } // Interface Men琚獺uman,Student鍜孍mployee瀹炵幇 // 鍥犱負榪欎笁涓被鍨嬮兘瀹炵幇浜嗚繖涓や釜鏂規硶 type Men interface { SayHi() Sing(lyrics string) } func main() { mike := Student{Human{"Mike", 25, "222-222-XXX"}, "MIT", 0.00} paul := Student{Human{"Paul", 26, "111-222-XXX"}, "Harvard", 100} sam := Employee{Human{"Sam", 36, "444-222-XXX"}, "Golang Inc.", 1000} tom := Employee{Human{"Tom", 37, "222-444-XXX"}, "Things Ltd.", 5000} //瀹氫箟Men綾誨瀷鐨勫彉閲廼 var i Men //i鑳藉瓨鍌⊿tudent i = mike銆銆銆銆 fmt.Println("This is Mike, a Student:") i.SayHi() i.Sing("November rain") //i涔熻兘瀛樺偍Employee i = tom fmt.Println("This is tom, an Employee:") i.SayHi() i.Sing("Born to be wild") //瀹氫箟浜唖lice Men fmt.Println("Let's use a slice of Men and see what happens") x := make([]Men, 3) //榪欎笁涓兘鏄笉鍚岀被鍨嬬殑鍏冪礌錛屼絾鏄粬浠疄鐜頒簡interface鍚屼竴涓帴鍙?/span> x[0], x[1], x[2] = paul, sam, mike for _, value := range x{ value.SayHi() } }
絀篿nterface(interface{})涓嶅寘鍚換浣曠殑method錛屾鍥犱負濡傛錛?span style="background-color: #ffff00;">鎵鏈夌殑綾誨瀷閮藉疄鐜頒簡絀篿nterface銆傜┖interface瀵逛簬鎻忚堪璧蜂笉鍒頒換浣曠殑浣滅敤(鍥犱負瀹冧笉鍖呭惈浠諱綍鐨刴ethod錛夛紝浣嗘槸絀篿nterface鍦ㄦ垜浠渶瑕佸瓨鍌ㄤ換鎰忕被鍨嬬殑鏁板肩殑鏃跺欑浉褰撴湁鐢紝鍥犱負瀹冨彲浠ュ瓨鍌ㄤ換鎰忕被鍨嬬殑鏁板箋傚畠鏈夌偣綾諱技浜嶤璇█鐨剉oid*綾誨瀷銆?/span>
// 瀹氫箟a涓虹┖鎺ュ彛 var a interface{} var i int = 5 s := "Hello world" // a鍙互瀛樺偍浠繪剰綾誨瀷鐨勬暟鍊?/span> a = i a = s
interface鐨勫彉閲忛噷闈㈠彲浠ュ瓨鍌ㄤ換鎰忕被鍨嬬殑鏁板鹼紙璇ョ被鍨嬪疄鐜頒簡interface錛夛紝閭d箞鎴戜滑鎬庝箞鍙嶅悜鐭ラ亾榪欎釜interface鍙橀噺閲岄潰瀹為檯淇濆瓨浜嗙殑鏄摢涓被鍨嬬殑瀵硅薄鍛紵鐩墠甯哥敤鐨勬湁涓ょ鏂規硶錛歴witch嫻嬭瘯銆丆omma-ok鏂█銆?/p>
switch嫻嬭瘯濡備笅錛?/p>
type Element interface{} type List [] Element type Person struct { name string age int } //鎵撳嵃 func (p Person) String() string { return "(name: " + p.name + " - age: "+strconv.Itoa(p.age)+ " years)" } func main() { list := make(List, 3) list[0] = 1 //an int list[1] = "Hello" //a string list[2] = Person{"Dennis", 70} for index, element := range list{ switch value := element.(type) { case int: fmt.Printf("list[%d] is an int and its value is %d\n", index, value) case string: fmt.Printf("list[%d] is a string and its value is %s\n", index, value) case Person: fmt.Printf("list[%d] is a Person and its value is %s\n", index, value) default: fmt.Println("list[%d] is of a different type", index) } } }
濡傛灉浣跨敤Comma-ok鏂█鐨勮瘽錛?/p>
func main() { list := make(List, 3) list[0] = 1 // an int list[1] = "Hello" // a string list[2] = Person{"Dennis", 70} for index, element := range list { if value, ok := element.(int); ok { fmt.Printf("list[%d] is an int and its value is %d\n", index, value) } else if value, ok := element.(string); ok { fmt.Printf("list[%d] is a string and its value is %s\n", index, value) } else if value, ok := element.(Person); ok { fmt.Printf("list[%d] is a Person and its value is %s\n", index, value) } else { fmt.Printf("list[%d] is of a different type\n", index) } } }
姝estruct綾誨瀷鍙互鍖呭惈涓涓尶鍚嶅瓧孌碉紝interface涔熷彲浠ュ祵濂楀彟澶栦竴涓帴鍙c?/p>
濡傛灉涓涓猧nterface1浣滀負interface2鐨勪竴涓祵鍏ュ瓧孌碉紝閭d箞interface2闅愬紡鐨勫寘鍚簡interface1閲岄潰鐨刴ethod銆?/p>
鎵璋撳弽灝勶紙reflect錛夊氨鏄兘媯鏌ョ▼搴忓湪榪愯鏃剁殑鐘舵併?/p>
浣跨敤reflect涓鑸垎鎴愪笁姝ワ紝涓嬮潰綆瑕佺殑璁茶В涓涓嬶細瑕佸幓鍙嶅皠鏄竴涓被鍨嬬殑鍊?榪欎簺鍊奸兘瀹炵幇浜嗙┖interface)錛岄鍏堥渶瑕佹妸瀹冭漿鍖栨垚reflect瀵硅薄(reflect.Type鎴栬卹eflect.Value錛屾牴鎹笉鍚岀殑鎯呭喌璋冪敤涓嶅悓鐨勫嚱鏁?銆傝繖涓ょ鑾峰彇鏂瑰紡濡備笅錛?/p>
t := reflect.TypeOf(i) //寰楀埌綾誨瀷鐨勫厓鏁版嵁,閫氳繃t鎴戜滑鑳借幏鍙栫被鍨嬪畾涔夐噷闈㈢殑鎵鏈夊厓绱?/span> v := reflect.ValueOf(i) //寰楀埌瀹為檯鐨勫鹼紝閫氳繃v鎴戜滑鑾峰彇瀛樺偍鍦ㄩ噷闈㈢殑鍊鹼紝榪樺彲浠ュ幓鏀瑰彉鍊?/span>
杞寲涓簉eflect瀵硅薄涔嬪悗鎴戜滑灝卞彲浠ヨ繘琛屼竴浜涙搷浣滀簡錛屼篃灝辨槸灝唕eflect瀵硅薄杞寲鎴愮浉搴旂殑鍊鹼紝渚嬪
tag := t.Elem().Field(0).Tag //鑾峰彇瀹氫箟鍦╯truct閲岄潰鐨勬爣絳?/span> name := v.Elem().Field(0).String() //鑾峰彇瀛樺偍鍦ㄧ涓涓瓧孌甸噷闈㈢殑鍊?/span>
鑾峰彇鍙嶅皠鍊艱兘榪斿洖鐩稿簲鐨勭被鍨嬪拰鏁板?/p>
var x float64 = 3.4 v := reflect.ValueOf(x) fmt.Println("type:", v.Type()) fmt.Println("kind is float64:", v.Kind() == reflect.Float64) fmt.Println("value:", v.Float())
鏈鍚庯紝鍙嶅皠鐨勮瘽錛岄偅涔堝弽灝勭殑瀛楁蹇呴』鏄彲淇敼鐨勶紝鎴戜滑鍓嶉潰瀛︿範榪囦紶鍊煎拰浼犲紩鐢紝榪欎釜閲岄潰涔熸槸涓鏍風殑閬撶悊銆傚弽灝勭殑瀛楁蹇呴』鏄彲璇誨啓鐨勬剰鎬濇槸錛屽鏋滀笅闈㈣繖鏍峰啓錛岄偅涔堜細鍙戠敓閿欒
var x float64 = 3.4 v := reflect.ValueOf(x) v.SetFloat(7.1)
濡傛灉瑕佷慨鏀圭浉搴旂殑鍊鹼紝蹇呴』榪欐牱鍐?/p>
var x float64 = 3.4 p := reflect.ValueOf(&x) v := p.Elem() v.SetFloat(7.1)
涓婇潰鍙槸瀵瑰弽灝勭殑綆鍗曚粙緇嶏紝鏇存繁鍏ョ殑鐞嗚В榪橀渶瑕佽嚜宸卞湪緙栫▼涓笉鏂殑瀹炶返銆?/p>
鍙傝冩枃妗o細
http://se77en.cc/2014/05/05/methods-interfaces-and-embedded-types-in-golang/
http://se77en.cc/2014/05/04/choose-whether-to-use-a-value-or-pointer-receiver-on-methods/
http://www.cnblogs.com/chenny7/p/4497969.html
func (p myType ) funcName ( a, b int , c string ) ( r , s int ) { return }
閫氳繃鍑芥暟瀹氫箟錛屾垜浠彲浠ョ湅鍒癎o涓嚱鏁板拰鍏朵粬璇█涓殑鍏辨у拰鐗規?/p>
Go涓嚱鏁扮殑鐗規ф槸闈炲父閰風殑錛岀粰鎴戜滑甯︽潵涓嶄竴鏍風殑緙栫▼浣撻獙銆?/p>
鍦℅o涓氳繃緇欏嚱鏁版爣鏄庢墍灞炵被鍨嬶紝鏉ョ粰璇ョ被鍨嬪畾涔夋柟娉曪紝涓婇潰鐨?nbsp;p myType
鍗寵〃紺虹粰myType澹版槑浜嗕竴涓柟娉曪紝 p myType
涓嶆槸蹇呴』鐨勩傚鏋滄病鏈夛紝鍒欑函綺規槸涓涓嚱鏁幫紝閫氳繃鍖呭悕縐拌闂俻ackageName.funcationName
濡傦細
//瀹氫箟鏂扮殑綾誨瀷double錛屼富瑕佺洰鐨勬槸緇檉loat64綾誨瀷鎵╁厖鏂規硶 type double float64 //鍒ゆ柇a鏄惁絳変簬b func (a double) IsEqual(b double) bool { var r = a - b if r == 0.0 { return true } else if r < 0.0 { return r > -0.0001 } return r < 0.0001 } //鍒ゆ柇a鏄惁絳変簬b func IsEqual(a, b float64) bool { var r = a - b if r == 0.0 { return true } else if r < 0.0 { return r > -0.0001 } return r < 0.0001 } func main() { var a double = 1.999999 var b double = 1.9999998 fmt.Println(a.IsEqual(b)) fmt.Println(a.IsEqual(3)) fmt.Println( IsEqual( (float64)(a), (float64)(b) ) ) }
涓婅堪紺轟緥涓?float64 鍩烘湰綾誨瀷鎵╁厖浜嗘柟娉旾sEqual錛岃鏂規硶涓昏鏄В鍐崇簿搴﹂棶棰樸?鍏舵柟娉曡皟鐢ㄦ柟寮忎負錛?nbsp;a.IsEqual(double)
錛屽鏋滀笉鎵╁厖鏂規硶錛屾垜浠彧鑳戒嬌鐢ㄥ嚱鏁?code style="margin: 0px 2px; padding: 0px 5px; border: 1px solid #eaeaea; background-color: #f8f8f8; border-radius: 3px; white-space: nowrap; font-family: monospace, Monaco;">IsEqual(a, b float64)
濡?nbsp;func IsEqual(a, b float64) bool
榪欎釜鏂規硶灝卞彧淇濈暀浜嗕竴涓被鍨嬪0鏄?姝ゆ椂鍏ュ弬a鍜宐鍧囨槸float64鏁版嵁綾誨瀷銆?榪欐牱涔熸槸鍙互鐨勶細 func IsEqual(a, b float64, accuracy int) bool
濡?nbsp;func Sum(args ...int)
鍙傛暟args鏄殑slice錛屽叾鍏冪礌綾誨瀷涓篿nt 銆傜粡甯鎬嬌鐢ㄧ殑fmt.Printf灝辨槸涓涓帴鍙椾換鎰忎釜鏁板弬鏁扮殑鍑芥暟 fmt.Printf(format string, args ...interface{})
鍓嶉潰鎴戜滑瀹氫箟鍑芥暟鏃惰繑鍥炲兼湁涓や釜r,s 銆傝繖鏄潪甯告湁鐢ㄧ殑錛屾垜鍦ㄥ啓C#浠g爜鏃訛紝甯稿父涓轟簡浠庡凡鏈夊嚱鏁頒腑鑾峰緱鏇村鐨勪俊鎭紝闇瑕佷慨鏀瑰嚱鏁扮鍚嶏紝浣跨敤out ,ref 絳夋柟寮忓幓鑾峰緱鏇村榪斿洖緇撴灉銆傝岀幇鍦ㄤ嬌鐢℅o鏃跺垯寰堢畝鍗曪紝鐩存帴鍦ㄨ繑鍥炲煎悗闈㈡坊鍔犺繑鍥炲弬鏁板嵆鍙?/p>
濡?鍦–#涓竴涓瓧絎︿覆杞崲涓篿nt綾誨瀷鏃墮昏緫浠g爜
int v=0; if ( int.TryPase("123456",out v) ) { //code }
鑰屽湪Go涓紝鍒欏彲浠ヨ繖鏍峰疄鐜?閫昏緫綺劇畝鑰屾槑紜?/p>
if v,isOk :=int.TryPase("123456") ; isOk { //code }
鍚屾椂鍦℅o涓緢澶氬嚱鏁板厖鍒嗗埄鐢ㄤ簡澶氳繑鍥炲?/p>
閭d箞濡傛灉鎴戝彧闇瑕佹煇涓涓繑鍥炲鹼紝鑰屼笉鍏沖績鍏朵粬榪斿洖鍊肩殑璇濓紝鎴戣濡備綍鍔炲憿錛?榪欐椂鍙互綆鍗曠殑浣跨敤絎﹀彿涓嬪垝綰?#8221;_“ 鏉ュ拷鐣ヤ笉鍏沖績鐨勮繑鍥炲箋傚錛?/p>
_, cos = math.Sincos(3.1415) //鍙渶瑕乧os璁$畻鐨勫?
鍓嶉潰鎴戜滑璇翠簡鍑芥暟鍙互鏈夊涓繑鍥炲鹼紝榪欓噷鎴戣繕瑕佽鐨勬槸錛屽湪鍑芥暟瀹氫箟鏃跺彲浠ョ粰鎵鏈夌殑榪斿洖鍊煎垎鍒懡鍚嶏紝榪欐牱灝辮兘鍦ㄥ嚱鏁頒腑浠繪剰浣嶇疆緇欎笉鍚岃繑鍥炲煎鍒訛紝鑰屼笉闇瑕佸湪return璇彞涓墠鎸囧畾榪斿洖鍊箋傚悓鏃朵篃鑳藉寮哄彲璇繪э紝涔熸彁楂榞odoc鎵鐢熸垚鏂囨。鐨勫彲璇繪?/p>
濡傛灉涓嶆敮鎸佸懡鍚嶈繑鍥炲鹼紝鎴戝彲鑳戒細鏄繖鏍峰仛鐨?/p>
func ReadFull(r Reader, buf []byte) (int, error) { var n int var err error for len(buf) > 0 { var nr int nr, err = r.Read(buf) n += nr if err !=nil { return n,err } buf = buf[nr:] } return n,err }
浣嗘敮鎸佺粰榪斿洖鍊煎懡鍚嶅悗錛屽疄闄呬笂灝辨槸鐪佺暐浜嗗彉閲忕殑澹版槑錛宺eturn鏃舵棤闇鍐欐垚return n,err
鑰屾槸灝嗙洿鎺ュ皢鍊艱繑鍥?/p>
func ReadFull(r Reader, buf []byte) (n int, err error) { for len(buf) > 0 && err == nil { var nr int nr, err = r.Read(buf) n += nr buf = buf[nr:] } return }
鍜孏o涓叾浠栦笢瑗夸竴鏍鳳紝鍑芥暟涔熸槸鍊鹼紝榪欐牱灝卞彲浠ュ0鏄庝竴涓嚱鏁扮被鍨嬬殑鍙橀噺錛屽皢鍑芥暟浣滀負鍙傛暟浼犻掋?/p>
澹版槑鍑芥暟涓哄肩殑鍙橀噺(鍖垮悕鍑芥暟:鍙祴鍊間釜鍙橀噺錛屼篃鍙洿鎺ユ墽琛?
//璧嬪?fc := func(msg string) { fmt.Println("you say :", msg) } fmt.Printf("%T \n", fc) fc("hello,my love") //鐩存帴鎵ц func(msg string) { fmt.Println("say :", msg) }("I love to code")
杈撳嚭緇撴灉濡備笅錛岃繖閲岃〃鏄巉c 鐨勭被鍨嬩負錛歠unc(string)
func(string) you say : hello,my love say : I love to code
灝嗗嚱鏁頒綔涓哄叆鍙傦紙鍥炶皟鍑芥暟錛夛紝鑳藉甫鏉ヤ究鍒┿傚鏃ュ織澶勭悊錛屼負浜嗙粺涓澶勭悊錛屽皢淇℃伅鍧囬氳繃鎸囧畾鍑芥暟鍘昏褰曟棩蹇楋紝涓旀槸鍚﹁褰曟棩蹇楄繕鏈夊紑鍏?/p>
func Log(title string, getMsg func() string) { //濡傛灉寮鍚棩蹇楄褰?鍒欒褰曟棩蹇? if true { fmt.Println(title, ":", getMsg()) } } //---------璋冪敤-------------- count := 0 msg := func() string { count++ return "鎮ㄦ病鏈夊嵆浣挎彁閱掓垜,宸茶Е鐘硶寰? } Log("error", msg) Log("warring", msg) Log("info", msg) fmt.Println(count)
榪欓噷杈撳嚭緇撴灉濡備笅錛宑ount 涔熷彂鐢熶簡鍙樺寲
error : 鎮ㄦ病鏈夊嵆浣挎彁閱掓垜,宸茶Е鐘硶寰?warring : 鎮ㄦ病鏈夊嵆浣挎彁閱掓垜,宸茶Е鐘硶寰?info : 鎮ㄦ病鏈夊嵆浣挎彁閱掓垜,宸茶Е鐘硶寰?3
浣犳湁娌℃湁娉ㄦ剰鍒頒笂闈㈢ず渚嬩腑鐨?nbsp;fc := func(msg string)...
錛屾棦鐒跺尶鍚嶅嚱鏁板彲浠ヨ祴鍊肩粰涓涓彉閲忥紝鍚屾椂鎴戜滑緇忓父榪欐牱緇檌nt璧嬪?nbsp;value := 2
,鏄惁鎴戜滑鍙互澹版槑func(string) 綾誨瀷 鍛紝褰撶劧鏄彲浠ョ殑銆?/p>
//涓涓褰曟棩蹇楃殑綾誨瀷錛歠unc(string) type saveLog func(msg string) //灝嗗瓧絎︿覆杞崲涓篿nt64,濡傛灉杞崲澶辮觸璋冪敤saveLog func stringToInt(s string, log saveLog) int64 { if value, err := strconv.ParseInt(s, 0, 0); err != nil { log(err.Error()) return 0 } else { return value } } //璁板綍鏃ュ織娑堟伅鐨勫叿浣撳疄鐜?func myLog(msg string) { fmt.Println("Find Error:", msg) } func main() { stringToInt("123", myLog) //杞崲鏃跺皢璋冪敤mylog璁板綍鏃ュ織 stringToInt("s", myLog) }
榪欓噷鎴戜滑瀹氫箟浜嗕竴涓被鍨嬶紝涓撻棬鐢ㄤ綔璁板綍鏃ュ織鐨勬爣鍑嗘帴鍙c傚湪stringToInt鍑芥暟涓鏋滆漿鎹㈠け璐ュ垯璋冪敤鎴戣嚜宸卞畾涔夌殑鎺ュ彛鍑芥暟榪涜鏃ュ織澶勭悊錛岃嚦浜庢渶緇堟墽琛岀殑鍝釜鍑芥暟錛屽垯鏃犻渶鍏沖績銆?/p>
defer 鍙堟槸涓涓垱鏂幫紝瀹冪殑浣滅敤鏄細寤惰繜鎵ц錛屽湪澹版槑鏃朵笉浼氱珛鍗蟲墽琛岋紝鑰屾槸鍦ㄥ嚱鏁皉eturn鍚庢椂鎸夌収鍚庤繘鍏堝嚭鐨勫師鍒欎緷嬈℃墽琛屾瘡涓涓猟efer銆傝繖鏍峰甫鏉ョ殑濂藉鏄紝鑳界‘淇濇垜浠畾涔夌殑鍑芥暟鑳界櫨鍒嗕箣鐧捐兘澶熻鎵ц鍒幫紝榪欐牱灝辮兘鍋氬緢澶氭垜浠兂鍋氱殑浜嬶紝濡傞噴鏀捐祫婧愶紝娓呯悊鏁版嵁錛岃褰曟棩蹇楃瓑
榪欓噷鎴戜滑閲嶇偣鏉ヨ鏄庝笅defer鐨勬墽琛岄『搴?/p>
func deferFunc() int { index := 0 fc := func() { fmt.Println(index, "鍖垮悕鍑芥暟1") index++ defer func() { fmt.Println(index, "鍖垮悕鍑芥暟1-1") index++ }() } defer func() { fmt.Println(index, "鍖垮悕鍑芥暟2") index++ }() defer fc() return func() int { fmt.Println(index, "鍖垮悕鍑芥暟3") index++ return index }() } func main() { deferFunc() }
榪欓噷杈撳嚭緇撴灉濡備笅錛?/p>
0 鍖垮悕鍑芥暟3 1 鍖垮悕鍑芥暟1 2 鍖垮悕鍑芥暟1-1 3 鍖垮悕鍑芥暟2
鏈夊涓嬬粨璁猴細
鍙﹀錛屾垜浠父浣跨敤defer鍘誨叧闂璉O,鍦ㄦ甯告墦寮鏂囦歡鍚庯紝灝辯珛鍒誨0鏄庝竴涓猟efer錛岃繖鏍峰氨涓嶄細蹇樿鍏抽棴鏂囦歡錛屼篃鑳戒繚璇佸湪鍑虹幇寮傚父絳変笉鍙鏂欑殑鎯呭喌涓嬩篃鑳藉叧闂枃浠躲傝屼笉鍍忓叾浠栬璦錛?code style="margin: 0px 2px; padding: 0px 5px; border: 1px solid #eaeaea; background-color: #f8f8f8; border-radius: 3px; white-space: nowrap; font-family: monospace, Monaco;">try-catch 鎴栬?nbsp;using()
鏂瑰紡榪涜澶勭悊銆?/p>
file , err :=os.Open(file) if err != nil { return err } defer file.Close() //dosomething with file
鍚庣畫錛屾垜灝嗚璁猴細 浣滅敤鍩熴佷紶鍊煎拰浼犳寚閽?浠ュ強 淇濈暀鍑芥暟init(),main()
鏈瑪璁頒腑鎵鍐欎唬鐮佸瓨鍌ㄤ綅緗細
浠ュ墠鍏蟲敞鐨勬暟鎹瓨鍌ㄨ繃紼嬩笉澶噦鍏朵腑濂ュ錛屾渶榪戦亣鍒拌法鏁版嵁搴?/a>錛屽悓鏃跺澶氫釜琛ㄨ繘琛孋URD錛圕reate澧炪乁pdate鏀廣丷ead璇匯丏elete鍒狅級錛屾庝箞鎵嶈兘璁╃箒鐞愮殑鏁版嵁CURD鍚屾鍙樺緱鏇村鏄撳憿錛熺浉淇″緢澶氫漢浼氶鍏堟兂鍒頒簡MySQL瀛樺偍榪囩▼銆佽Е鍙戝櫒錛岃繖縐嶆兂娉曠‘瀹炰笉閿欍備簬鏄ザ鏈夊叴瓚e湴浜茶嚜鍐欎簡CUD錛堝銆佹敼銆佸垹錛夎Е鍙戝櫒鐨勫疄渚嬶紝鐢ㄨЕ鍙戝櫒瀹炵幇澶氳〃鏁版嵁鍚屾鏇存柊銆?/p>
瀹氫箟錛?浣曚負MySQL瑙﹀彂鍣紵
鍦∕ySQL Server閲岄潰涔熷氨鏄鏌愪竴涓〃鐨勪竴瀹氱殑鎿嶄綔錛岃Е鍙戞煇縐嶆潯浠訛紙Insert,Update,Delete 絳夛級錛屼粠鑰岃嚜鍔ㄦ墽琛岀殑涓孌電▼搴忋備粠榪欑鎰忎箟涓婅瑙﹀彂鍣ㄦ槸涓涓壒孌婄殑瀛樺偍榪囩▼銆備笅闈㈤氳繃MySQL瑙﹀彂鍣ㄥ疄渚嬶紝鏉ヤ簡瑙d竴涓嬭Е鍙戝櫒鐨勫伐浣滆繃紼嬪惂錛?/p>
涓銆佸垱寤篗ySQL瀹炰緥鏁版嵁琛細
鍦╩ysql鐨勯粯璁ょ殑嫻嬭瘯test鏁版嵁搴撲笅錛屽垱寤轟袱涓〃t_a涓巘_b錛?/p>
鍦╰_a琛ㄤ笂鍒嗗垱寤轟竴涓狢UD錛堝銆佹敼銆佸垹錛?涓Е鍙戝櫒錛屽皢t_a鐨勮〃鏁版嵁涓巘_b鍚屾瀹炵幇CUD錛屾敞鎰忓垱寤鴻Е鍙戝櫒姣忎釜琛ㄥ悓綾諱簨浠舵湁涓斾粎鏈変竴涓搴旇Е鍙戝櫒錛屼負浠涔堝彧鑳藉涓涓Е鍙戝櫒錛屼笉瑙i噴鍟︼紝鐪婱YSQL鐨勮鏄庡府鍔╂枃妗e惂銆?/p>
浜屻佸垱寤篗ySQL瀹炰緥瑙﹀彂鍣細
鍦ㄥ疄渚嬫暟鎹〃t_a涓婁緷嬈℃寜鐓т笅闈㈡楠ゅ垱寤簍r_a_insert銆乼r_a_update銆乼r_a_delete涓変釜瑙﹀彂鍣?/p>
1銆佸垱寤篒NSERT瑙﹀彂鍣╰rigger_a_insert錛?/strong>
涓夈佹祴璇昅ySQL瀹炰緥瑙﹀彂鍣細
鍒嗗埆嫻嬭瘯瀹炵幇t_a涓巘_b瀹炵幇鏁版嵁鍚屾CUD(澧炪佹敼銆佸垹)3涓猅riggers
1銆佹祴璇昅ySQL鐨勫疄渚媡r_a_insert瑙﹀彂鍣細
鍦╰_a琛ㄤ腑鏂板涓鏉℃暟鎹紝鐒跺悗鍒嗗埆鏌ヨt_a/t_b琛ㄧ殑鏁版嵁鏄惁鏁版嵁鍚屾錛屾祴璇曡Е鍙戝櫒鎴愬姛鏍囧織錛宼_a琛ㄦ棤璁哄湪浣曠鎯呭喌涓嬶紝鏂板浜嗕竴鏉℃垨澶氭潯璁板綍闆嗘椂錛屾病鏈塼_b琛ㄥ仛浠諱綍鏁版嵁insert鎿嶄綔錛屽畠鍚屾椂鏂板浜嗕竴鏍風殑澶氭潯璁板綍闆嗐?/p>
涓嬮潰鏉ヨ繘琛孧ySQL瑙﹀彂鍣ㄥ疄渚嬫祴璇曪細
2銆佹祴璇昅ySQL鐨勫疄渚媡r_a_update銆乼r_a_delete瑙﹀彂鍣細
榪欎袱涓狹ySQL瑙﹀彂鍣ㄦ祴璇曞師鐞嗐佹楠や笌tr_a_insert瑙﹀彂鍣ㄤ竴鏍風殑錛屽厛淇敼/鍒犻櫎涓鏉℃暟鎹紝鐒跺悗鍒嗗埆鏌ョ湅t_a銆乼_b琛ㄧ殑鏁版嵁鍙樺寲鎯呭喌錛屾暟鎹彉鍖栧悓姝ヨ鏄嶵rigger瀹炰緥鎴愬姛錛屽惁鍒欓渶瑕侀愭鎺掓煡閿欒鍘熷洜銆?/p>
涓栫晫涓婁換浣曚竴縐嶄簨鐗╅兘鍏跺叾浼樼偣鍜岀己鐐癸紝浼樼偣涓庣己鐐規槸鑷韓涓涓浉瀵圭珛鐨勯潰銆傚綋鐒惰繖閲屼笉鏄己璋?#8220;涓栫晫闈為粦鍗崇櫧”寮忕殑“浜屽厓璁?#8221;錛?#8220;瀛樺湪鍗沖悎鐞?#8221;鍢涖傚綋鐒?MySQL瑙﹀彂鍣ㄧ殑浼樼偣涓嶈浜嗭紝璇翠竴涓嬩笉瓚充箣澶勶紝MySQL Trigger娌℃湁寰堝ソ鐨勮皟璇曘佺鐞嗙幆澧冿紝闅句簬鍦ㄥ悇縐嶇郴緇熺幆澧冧笅嫻嬭瘯錛屾祴璇曟瘮MySQL瀛樺偍榪囩▼瑕侀毦錛屾墍浠ュ緩璁湪鐢熸垚鐜涓嬶紝灝介噺鐢ㄥ瓨鍌ㄨ繃紼嬫潵浠f浛 MySQL瑙﹀彂鍣ㄣ?/p>
鏈瘒緇撴潫鍓嶅啀寮鴻皟涓涓嬶紝鏀寔瑙﹀彂鍣ㄧ殑MySQL鐗堟湰闇瑕?.0浠ヤ笂錛?.0浠ュ墠鐗堟湰鐨凪ySQL鍗囩駭鍒?.0浠ュ悗鐗堟湰鏂瑰彲浣跨敤瑙﹀彂鍣ㄥ摝錛?/p>
If you prefer command line client, then you can install it on your Linux with the following command.
sudo apt-get install python-pip sudo pip install shadowsocks
Yes, you can use the above commands to install shadowsocks client on ubuntu. But it will install it under ~/.local/bin/ directory and it causes loads of trouble. So I suggest using su to become root first and then issue the following two commands.
apt-get install python-pip pip install shadowsocks
sudo yum install python-setuptools or sudo dnf install python-setuptools sudo easy_install pip sudo pip install shadowsocks
sudo zypper install python-pip sudo pip install shadowsocks
sudo pacman -S python-pip sudo pip install shadowsocks
As you can see the command of installing shadowsocks client is the same to the command of installing shadowsocks server, because the above command will install both the client and the server. You can verify this by looking at the installation script output
Downloading/unpacking shadowsocks Downloading shadowsocks-2.8.2.tar.gz Running setup.py (path:/tmp/pip-build-PQIgUg/shadowsocks/setup.py) egg_info for package shadowsocks Installing collected packages: shadowsocks Running setup.py install for shadowsocks Installing sslocal script to /usr/local/bin Installing ssserver script to /usr/local/bin Successfully installed shadowsocks Cleaning up...
sslocal is the client software and ssserver is the server software. On some Linux distros such as ubuntu, the shadowsocks client sslocal is installed under /usr/local/bin. On Others such as Archsslocal is installed under /usr/bin/. Your can use whereis command to find the exact location.
user@debian:~$ whereis sslocal sslocal: /usr/local/bin/sslocal
we will create a configuration file under /etc/
sudo vi /etc/shadowsocks.json
Put the following text in the file. Replace server-ip with your actual IP and set a password.
{
"server":"server-ip",
"server_port":8000,
"local_address": "127.0.0.1",
"local_port":1080,
"password":"your-password",
"timeout":600,
"method":"aes-256-cfb"
}
Save and close the file. Next start the client using command line
sslocal -c /etc/shadowsocks.json
sudo sslocal -c /etc/shadowsocks.json -d start
Edit /etc/rc.local file
sudo vi /etc/rc.local
Put the following line above the exit 0 line:
sudo sslocal -c /etc/shadowsocks.json -d start
Save and close the file. Next time you start your computer, shadowsocks client will automatically start and connect to your shadowsocks server.
After you rebooted your computer, enter the following command in terminal:
sudo systemctl status rc-local.service
If your sslocal command works then you will get this ouput:
● rc-local.service - /etc/rc.local
Compatibility Loaded: loaded (/etc/systemd/system/rc-local.service; enabled; vendor preset: enabled)
Active: active (running) since Fri 2015-11-27 03:19:25 CST; 2min 39s ago
Process: 881 ExecStart=/etc/rc.local start (code=exited, status=0/SUCCESS)
CGroup: /system.slice/rc-local.service
├─ 887 watch -n 60 su matrix -c ibam
└─1112 /usr/bin/python /usr/local/bin/sslocal -c /etc/shadowsocks....
As you can see from the last line, the sslocal command created a process whose pid is 1112 on my machine. It means shadowsocks client is running smoothly. And of course you can tell your browser to connect through your shadowsocks client to see if everything goes well.
If for some reason your /etc/rc.local script won’t run, then check the following post to find the solution.
If you prefer command line client, then you can install it on your Linux with the following command.
sudo apt-get install python-pip sudo pip install shadowsocks
Yes, you can use the above commands to install shadowsocks client on ubuntu. But it will install it under ~/.local/bin/ directory and it causes loads of trouble. So I suggest using su to become root first and then issue the following two commands.
apt-get install python-pip pip install shadowsocks
sudo yum install python-setuptools or sudo dnf install python-setuptools sudo easy_install pip sudo pip install shadowsocks
sudo zypper install python-pip sudo pip install shadowsocks
sudo pacman -S python-pip sudo pip install shadowsocks
As you can see the command of installing shadowsocks client is the same to the command of installing shadowsocks server, because the above command will install both the client and the server. You can verify this by looking at the installation script output
Downloading/unpacking shadowsocks Downloading shadowsocks-2.8.2.tar.gz Running setup.py (path:/tmp/pip-build-PQIgUg/shadowsocks/setup.py) egg_info for package shadowsocks Installing collected packages: shadowsocks Running setup.py install for shadowsocks Installing sslocal script to /usr/local/bin Installing ssserver script to /usr/local/bin Successfully installed shadowsocks Cleaning up...
sslocal is the client software and ssserver is the server software. On some Linux distros such as ubuntu, the shadowsocks client sslocal is installed under /usr/local/bin. On Others such as Archsslocal is installed under /usr/bin/. Your can use whereis command to find the exact location.
user@debian:~$ whereis sslocal sslocal: /usr/local/bin/sslocal
we will create a configuration file under /etc/
sudo vi /etc/shadowsocks.json
Put the following text in the file. Replace server-ip with your actual IP and set a password.
{ "server":"server-ip", "server_port":8000, "local_address": "127.0.0.1", "local_port":1080, "password":"your-password", "timeout":600, "method":"aes-256-cfb" }
Save and close the file. Next start the client using command line
sslocal -c /etc/shadowsocks.json
sudo sslocal -c /etc/shadowsocks.json -d start
Edit /etc/rc.local file
sudo vi /etc/rc.local
Put the following line above the exit 0 line:
sudo sslocal -c /etc/shadowsocks.json -d start
Save and close the file. Next time you start your computer, shadowsocks client will automatically start and connect to your shadowsocks server.
After you rebooted your computer, enter the following command in terminal:
sudo systemctl status rc-local.service
If your sslocal command works then you will get this ouput:
● rc-local.service - /etc/rc.local Compatibility
Loaded: loaded (/etc/systemd/system/rc-local.service; enabled; vendor preset: enabled)
Active: active (running) since Fri 2015-11-27 03:19:25 CST; 2min 39s ago
Process: 881 ExecStart=/etc/rc.local start (code=exited, status=0/SUCCESS)
CGroup: /system.slice/rc-local.service
├─ 887 watch -n 60 su matrix -c ibam
└─1112 /usr/bin/python /usr/local/bin/sslocal -c /etc/shadowsocks....
As you can see from the last line, the sslocal command created a process whose pid is 1112 on my machine. It means shadowsocks client is running smoothly. And of course you can tell your browser to connect through your shadowsocks client to see if everything goes well.
If for some reason your /etc/rc.local script won’t run, then check the following post to find the solution.
How to enable /etc/rc.local with Systemd
package com.abin.lee.util;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.*;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.config.CookieSpecs;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;
import javax.net.ssl.*;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.UnknownHostException;
import java.nio.charset.Charset;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.*;
/**
* Created with IntelliJ IDEA.
* User: abin
* Date: 16-4-18
* Time: 涓婂崍10:24
* To change this template use File | Settings | File Templates.
*/
public class HttpClientUtil {
private static CloseableHttpClient httpsClient = null;
private static CloseableHttpClient httpClient = null;
static {
httpClient = getHttpClient();
httpsClient = getHttpsClient();
}
public static CloseableHttpClient getHttpClient() {
try {
httpClient = HttpClients.custom()
.setConnectionManager(PoolManager.getHttpPoolInstance())
.setConnectionManagerShared(true)
.setDefaultRequestConfig(requestConfig())
.setRetryHandler(retryHandler())
.build();
} catch (Exception e) {
e.printStackTrace();
}
return httpClient;
}
public static CloseableHttpClient getHttpsClient() {
try {
//Secure Protocol implementation.
SSLContext ctx = SSLContext.getInstance("SSL");
//Implementation of a trust manager for X509 certificates
TrustManager x509TrustManager = new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] xcs,
String string) throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] xcs,
String string) throws CertificateException {
}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
ctx.init(null, new TrustManager[]{x509TrustManager}, null);
//棣栧厛璁劇疆鍏ㄥ眬鐨勬爣鍑哻ookie絳栫暐
// RequestConfig requestConfig = RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD_STRICT).build();
ConnectionSocketFactory connectionSocketFactory = new SSLConnectionSocketFactory(ctx, hostnameVerifier);
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.INSTANCE)
.register("https", connectionSocketFactory).build();
// 璁劇疆榪炴帴姹?br /> httpsClient = HttpClients.custom()
.setConnectionManager(PoolsManager.getHttpsPoolInstance(socketFactoryRegistry))
.setConnectionManagerShared(true)
.setDefaultRequestConfig(requestConfig())
.setRetryHandler(retryHandler())
.build();
} catch (Exception e) {
e.printStackTrace();
}
return httpsClient;
}
// 閰嶇疆璇鋒眰鐨勮秴鏃惰緗?br /> //棣栧厛璁劇疆鍏ㄥ眬鐨勬爣鍑哻ookie絳栫暐
public static RequestConfig requestConfig(){
RequestConfig requestConfig = RequestConfig.custom()
.setCookieSpec(CookieSpecs.STANDARD_STRICT)
.setConnectionRequestTimeout(20000)
.setConnectTimeout(20000)
.setSocketTimeout(20000)
.build();
return requestConfig;
}
public static HttpRequestRetryHandler retryHandler(){
//璇鋒眰閲嶈瘯澶勭悊
HttpRequestRetryHandler httpRequestRetryHandler = new HttpRequestRetryHandler() {
public boolean retryRequest(IOException exception,int executionCount, HttpContext context) {
if (executionCount >= 5) {// 濡傛灉宸茬粡閲嶈瘯浜?嬈★紝灝辨斁寮?br /> return false;
}
if (exception instanceof NoHttpResponseException) {// 濡傛灉鏈嶅姟鍣ㄤ涪鎺変簡榪炴帴錛岄偅涔堝氨閲嶈瘯
return true;
}
if (exception instanceof SSLHandshakeException) {// 涓嶈閲嶈瘯SSL鎻℃墜寮傚父
return false;
}
if (exception instanceof InterruptedIOException) {// 瓚呮椂
return false;
}
if (exception instanceof UnknownHostException) {// 鐩爣鏈嶅姟鍣ㄤ笉鍙揪
return false;
}
if (exception instanceof ConnectTimeoutException) {// 榪炴帴琚嫆緇?br /> return false;
}
if (exception instanceof SSLException) {// ssl鎻℃墜寮傚父
return false;
}
HttpClientContext clientContext = HttpClientContext.adapt(context);
HttpRequest request = clientContext.getRequest();
// 濡傛灉璇鋒眰鏄箓絳夌殑錛屽氨鍐嶆灝濊瘯
if (!(request instanceof HttpEntityEnclosingRequest)) {
return true;
}
return false;
}
};
return httpRequestRetryHandler;
}
//鍒涘緩HostnameVerifier
//鐢ㄤ簬瑙e喅javax.net.ssl.SSLException: hostname in certificate didn't match: <123.125.97.66> != <123.125.97.241>
static HostnameVerifier hostnameVerifier = new NoopHostnameVerifier(){
@Override
public boolean verify(String s, SSLSession sslSession) {
return super.verify(s, sslSession);
}
};
public static class PoolManager {
public static PoolingHttpClientConnectionManager clientConnectionManager = null;
private static int maxTotal = 200;
private static int defaultMaxPerRoute = 100;
private PoolManager(){
clientConnectionManager.setMaxTotal(maxTotal);
clientConnectionManager.setDefaultMaxPerRoute(defaultMaxPerRoute);
}
private static class PoolManagerHolder{
public static PoolManager instance = new PoolManager();
}
public static PoolManager getInstance() {
if(null == clientConnectionManager)
clientConnectionManager = new PoolingHttpClientConnectionManager();
return PoolManagerHolder.instance;
}
public static PoolingHttpClientConnectionManager getHttpPoolInstance() {
PoolManager.getInstance();
// System.out.println("getAvailable=" + clientConnectionManager.getTotalStats().getAvailable());
// System.out.println("getLeased=" + clientConnectionManager.getTotalStats().getLeased());
// System.out.println("getMax=" + clientConnectionManager.getTotalStats().getMax());
// System.out.println("getPending="+clientConnectionManager.getTotalStats().getPending());
return PoolManager.clientConnectionManager;
}
}
public static class PoolsManager {
public static PoolingHttpClientConnectionManager clientConnectionManager = null;
private static int maxTotal = 200;
private static int defaultMaxPerRoute = 100;
private PoolsManager(){
clientConnectionManager.setMaxTotal(maxTotal);
clientConnectionManager.setDefaultMaxPerRoute(defaultMaxPerRoute);
}
private static class PoolsManagerHolder{
public static PoolsManager instance = new PoolsManager();
}
public static PoolsManager getInstance(Registry<ConnectionSocketFactory> socketFactoryRegistry) {
if(null == clientConnectionManager)
clientConnectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
return PoolsManagerHolder.instance;
}
public static PoolingHttpClientConnectionManager getHttpsPoolInstance(Registry<ConnectionSocketFactory> socketFactoryRegistry) {
PoolsManager.getInstance(socketFactoryRegistry);
// System.out.println("getAvailable=" + clientConnectionManager.getTotalStats().getAvailable());
// System.out.println("getLeased=" + clientConnectionManager.getTotalStats().getLeased());
// System.out.println("getMax=" + clientConnectionManager.getTotalStats().getMax());
// System.out.println("getPending="+clientConnectionManager.getTotalStats().getPending());
return PoolsManager.clientConnectionManager;
}
}
public static String httpPost(Map<String, String> request, String httpUrl){
String result = "";
CloseableHttpClient httpClient = getHttpClient();
try {
if(MapUtils.isEmpty(request))
throw new Exception("璇鋒眰鍙傛暟涓嶈兘涓虹┖");
HttpPost httpPost = new HttpPost(httpUrl);
List<NameValuePair> nvps = new ArrayList<NameValuePair>();
for(Iterator<Map.Entry<String, String>> iterator=request.entrySet().iterator(); iterator.hasNext();){
Map.Entry<String, String> entry = iterator.next();
nvps.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
}
httpPost.setEntity(new UrlEncodedFormEntity(nvps, Consts.UTF_8));
System.out.println("Executing request: " + httpPost.getRequestLine());
CloseableHttpResponse response = httpClient.execute(httpPost);
result = EntityUtils.toString(response.getEntity());
System.out.println("Executing response: "+ result);
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return result;
}
public static String httpPost(String json, String httpUrl, Map<String, String> headers){
String result = "";
CloseableHttpClient httpClient = getHttpClient();
try {
if(StringUtils.isBlank(json))
throw new Exception("璇鋒眰鍙傛暟涓嶈兘涓虹┖");
HttpPost httpPost = new HttpPost(httpUrl);
for(Iterator<Map.Entry<String, String>> iterator=headers.entrySet().iterator();iterator.hasNext();){
Map.Entry<String, String> entry = iterator.next();
Header header = new BasicHeader(entry.getKey(), entry.getValue());
httpPost.setHeader(header);
}
httpPost.setEntity(new StringEntity(json, Charset.forName("UTF-8")));
System.out.println("Executing request: " + httpPost.getRequestLine());
CloseableHttpResponse response = httpClient.execute(httpPost);
result = EntityUtils.toString(response.getEntity());
System.out.println("Executing response: "+ result);
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return result;
}
public static String httpGet(String httpUrl, Map<String, String> headers) {
String result = "";
CloseableHttpClient httpClient = getHttpClient();
try {
HttpGet httpGet = new HttpGet(httpUrl);
System.out.println("Executing request: " + httpGet.getRequestLine());
for(Iterator<Map.Entry<String, String>> iterator=headers.entrySet().iterator();iterator.hasNext();){
Map.Entry<String, String> entry = iterator.next();
Header header = new BasicHeader(entry.getKey(), entry.getValue());
httpGet.setHeader(header);
}
CloseableHttpResponse response = httpClient.execute(httpGet);
result = EntityUtils.toString(response.getEntity());
System.out.println("Executing response: "+ result);
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return result;
}
public static String httpGet(String httpUrl) {
String result = "";
CloseableHttpClient httpClient = getHttpClient();
try {
HttpGet httpGet = new HttpGet(httpUrl);
System.out.println("Executing request: " + httpGet.getRequestLine());
CloseableHttpResponse response = httpClient.execute(httpGet);
result = EntityUtils.toString(response.getEntity());
System.out.println("Executing response: "+ result);
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return result;
}
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.1</version>
</dependency>
褰撴垜浠湁澶ч噺 Redis 鎴?Memcached 鐨勬椂鍊欙紝閫氬父鍙兘閫氳繃瀹㈡埛绔殑涓浜涙暟鎹垎閰嶇畻娉曪紙姣斿涓鑷存у搱甯岋級錛?/span>鏉ュ疄鐜伴泦緹ゅ瓨鍌ㄧ殑鐗規с?/span>铏界劧Redis 2.6鐗堟湰宸茬粡鍙戝竷Redis Cluster錛屼絾榪樹笉鏄緢鎴愮啛閫傜敤姝e紡鐢熶駭鐜銆?span style="color:#333333; font-family:Helvetica,Tahoma,Arial,sans-serif; font-size:14px; line-height:25.200000762939453px"> Redis 鐨?Cluster 鏂規榪樻病鏈夋寮忔帹鍑轟箣鍓嶏紝鎴戜滑閫氳繃 Proxy 鐨勬柟寮忔潵瀹炵幇闆嗙兢瀛樺偍銆?/span>
Twitter錛屼笘鐣屾渶澶х殑Redis闆嗙兢涔嬩竴閮ㄧ講鍦═witter鐢ㄤ簬涓虹敤鎴鋒彁渚涙椂闂磋醬鏁版嵁銆俆witter Open Source閮ㄩ棬鎻愪緵浜員wemproxy銆?/span>
Twemproxy,涔熷彨nutcraker銆傛槸涓涓猼wtter寮婧愮殑涓涓猺edis鍜宮emcache浠g悊鏈嶅姟鍣ㄣ?redis浣滀負涓涓珮鏁堢殑緙撳瓨鏈嶅姟鍣紝闈炲父鍏鋒湁搴旂敤浠峰箋備絾鏄綋浣跨敤姣旇緝澶氱殑鏃跺欙紝灝卞笇鏈涘彲浠ラ氳繃鏌愮鏂瑰紡 緇熶竴榪?/span>琛岀鐞嗐傞伩鍏嶆瘡涓簲鐢ㄦ瘡涓鎴風綆$悊榪炴帴鐨勬澗鏁fс傚悓鏃跺湪涓瀹氱▼搴︿笂鍙樺緱鍙互鎺у埗銆?/p> Twemproxy鏄竴涓揩閫熺殑鍗曠嚎紼嬩唬鐞嗙▼搴忥紝鏀寔Memcached ASCII鍗忚鍜屾洿鏂扮殑Redis鍗忚錛?/span> 瀹冨叏閮ㄧ敤C鍐欐垚錛屼嬌鐢ˋpache 2.0 License鎺堟潈銆傞」鐩湪Linux涓婂彲浠ュ伐浣滐紝鑰屽湪OSX涓婃棤娉曠紪璇戯紝鍥犱負瀹冧緷璧栦簡epoll API. Twemproxy 閫氳繃寮曞叆涓涓唬鐞嗗眰錛屽彲浠ュ皢鍏跺悗绔殑澶氬彴 Redis 鎴?Memcached 瀹炰緥榪涜緇熶竴綆$悊涓庡垎閰嶏紝浣垮簲鐢ㄧ▼搴忓彧闇瑕佸湪 Twemproxy 涓婅繘琛屾搷浣滐紝鑰屼笉鐢ㄥ叧蹇冨悗闈㈠叿浣撴湁澶氬皯涓湡瀹炵殑 Redis 鎴?Memcached 瀛樺偍銆?/span> 2銆?/span>twemproxy鐗規э細 鏀寔澶辮觸鑺傜偣鑷姩鍒犻櫎 鏀寔璁劇疆HashTag 鍑忓皯涓巖edis鐨勭洿鎺ヨ繛鎺ユ暟 鑷姩鍒嗙墖鍒板悗绔涓猺edis瀹炰緥涓?/p> 閬垮厤鍗曠偣闂 鏀寔redis pipelining request 鏀寔璇鋒眰鐨勬祦寮忎笌鎵瑰鐞嗭紝闄嶄綆鏉ュ洖鐨勬秷鑰?/span> 鏀寔鐘舵佺洃鎺?/p> 楂樺悶鍚愰噺 鍙﹀鍙互淇敼redis鐨勬簮浠g爜錛屾娊鍙栧嚭redis涓殑鍓嶅崐閮ㄥ垎錛屼綔涓轟竴涓腑闂翠唬鐞嗗眰銆傛渶緇堥兘鏄氳繃linux涓嬬殑epoll 浜嬩歡鏈哄埗鎻愰珮騫跺彂鏁堢巼錛屽叾涓璶utcraker鏈韓涔熸槸浣跨敤epoll鐨勪簨浠舵満鍒躲傚茍涓斿湪鎬ц兘嫻嬭瘯涓婄殑琛ㄧ幇闈炲父鍑鴻壊銆?/p>
3銆乼wemproxy闂涓庝笉瓚?/span>
4銆佸畨瑁呬笌閰嶇疆
apt-get install libtool
git clone git://github.com/twitter/twemproxy.git
cd twemproxy
autoreconf -fvi
./configure --enable-debug=log
make
src/nutcracker -h
listen: 127.0.0.1:6379 #浣跨敤鍝釜绔彛鍚姩Twemproxy
redis: true #鏄惁鏄疪edis鐨刾roxy
hash: fnv1a_64 #鎸囧畾鍏蜂綋鐨刪ash鍑芥暟
distribution: ketama #鍏蜂綋鐨刪ash綆楁硶
auto_eject_hosts: true #鏄惁鍦ㄧ粨鐐規棤娉曞搷搴旂殑鏃跺欎復鏃舵憳闄ょ粨鐐?
timeout: 400 #瓚呮椂鏃墮棿錛堟縐掞級
server_retry_timeout: 2000 #閲嶈瘯鐨勬椂闂達紙姣錛?
server_failure_limit: 1 #緇撶偣鏁呴殰澶氬皯嬈″氨綆楁憳闄ゆ帀
servers: #涓嬮潰琛ㄧず鎵鏈夌殑Redis鑺傜偣錛圛P:绔彛鍙?鏉冮噸錛?
- 127.0.0.1:6380:1
- 127.0.0.1:6381:1
- 127.0.0.1:6382:1
redis2:
listen: 0.0.0.0:10000
redis: true
hash: fnv1a_64
distribution: ketama
auto_eject_hosts: false
timeout: 400
servers:
- 127.0.0.1:6379:1
- 127.0.0.1:6380:1
- 127.0.0.1:6381:1
- 127.0.0.1:6382:1
浣犲彲浠ュ悓鏃跺紑鍚涓?Twemproxy 瀹炰緥錛屽畠浠兘鍙互榪涜璇誨啓錛岃繖鏍蜂綘鐨勫簲鐢ㄧ▼搴忓氨鍙互瀹屽叏閬垮厤鎵璋撶殑鍗曠偣鏁呴殰銆?
]]>