友链
导航
These are the good times in your life,
so put on a smile and it'll be alright
友链
导航
rune
is an alias for int32(一个 utf8 字符)iota
iota: Elegant Constants in Golang - Blog | Splice // e.g.1 type Stereotype int const ( TypicalNoob Stereotype = iota // 0 TypicalHipster // 1 TypicalUnixWizard // 2 TypicalStartupFounder // 3 ) // e.g.2 type ByteSize float64 const ( _ = iota // ignore first value by assigning to blank identifier KB ByteSize = 1 << (10 * iota) // 1,000 MB // 1,000,000 GB // ... TB PB EB ZB YB )
golang 的 time.Format() 要用 2006 作为年、1 作为月、2 作为日、3/15 作为小时、4 作为分、5 作为秒、MST 作为时区
官方设计如下:
The layout string used by the Parse function and Format method shows by example how the reference time should be represented. We stress that one must show how the reference time is formatted, not a time of the user's choosing. Thus each layout string is a representation of the time stamp, Jan 2 15:04:05 2006 MST An easy way to remember this value is that it holds, when presented in this order, the values (lined up with the elements above): 1 2 3 4 5 6 -7 There are some wrinkles illustrated below.
有一个测试网站:http://gotime.agardner.me/
// NullString represents a string that may be null. // NullString implements the Scanner interface so // it can be used as a scan destination: // // var s NullString // err := db.QueryRow("SELECT name FROM foo WHERE id=?", id).Scan(&s) // ... // if s.Valid { // // use s.String // } else { // // NULL value // } // type NullString struct { String string Valid bool // Valid is true if String is not NULL } // Scan implements the Scanner interface. func (ns *NullString) Scan(value interface{}) error { if value == nil { ns.String, ns.Valid = "", false return nil } ns.Valid = true return convertAssign(&ns.String, value) } // Value implements the driver Valuer interface. func (ns NullString) Value() (driver.Value, error) { if !ns.Valid { return nil, nil } return ns.String, nil }
要点:
import ( "math/rand" "net/http" + "sync" "time" // ... type VolumeServer struct { masterNode string + mnLock sync.RWMutex pulseSeconds int // ... vs := &VolumeServer{ - masterNode: masterNode, pulseSeconds: pulseSeconds, dataCenter: dataCenter, rack: rack, FixJpgOrientation: fixJpgOrientation, } + vs.SetMasterNode(masterNode) // ... - vs.store.SetBootstrapMaster(vs.masterNode) + + vs.store.SetBootstrapMaster(vs.GetMasterNode()) // ... +func (vs *VolumeServer) GetMasterNode() string { + vs.mnLock.RLock() + defer vs.mnLock.RUnlock() + return vs.masterNode +} + +func (vs *VolumeServer) SetMasterNode(masterNode string) { + vs.mnLock.Lock() + defer vs.mnLock.Unlock() + vs.masterNode = masterNode +} +
var wg sync.WaitGroup var urls = []string{ "http://www.golang.org/", "http://www.google.com/", "http://www.somestupidname.com/", } for _, url := range urls { // Increment the WaitGroup counter. wg.Add(1) // Launch a goroutine to fetch the URL. go func(url string) { // Decrement the counter when the goroutine completes. defer wg.Done() // Fetch the URL. http.Get(url) }(url) } // Wait for all HTTP fetches to complete. wg.Wait()
// func (r *Request) FormFile(key string) (multipart.File, *multipart.FileHeader, error) file, fileHeader, err := c.Request.FormFile("file") // 转 string scanner := bufio.NewScanner(file) for scanner.Scan() { // fmt.Println(scanner.Text()) // Println will add back the final '\n' content += scanner.Text() + "\n" } if err := scanner.Err(); err != nil { // fmt.Fprintln(os.Stderr, "reading standard input:", err) }
运行测试:
# Run all tests. $ go test $ go test -run '' # 查看用例执行详情 $ go test -v # 查看覆盖率 $ go test --cover $ go test -run Foo # Run top-level tests matching "Foo", such as "TestFooBar". $ go test -run Foo/A= # For top-level tests matching "Foo", run subtests matching "A=". $ go test -run /A=1 # For all top-level tests, run subtests matching "A=1".
func ParseInt(s string, base int, bitSize int) (i int64, err error)
ParseInt interprets a string s in the given base (2 to 36) and returns the corresponding value i. If base == 0, the base is implied by the string's prefix: base 16 for “0x”, base 8 for “0”, and base 10 otherwise.
The bitSize argument specifies the integer type that the result must fit into. Bit sizes 0, 8, 16, 32, and 64 correspond to int, int8, int16, int32, and int64.
func FormatInt(i int64, base int) string
FormatInt returns the string representation of i in the given base, for 2 ⇐ base ⇐ 36. The result uses the lower-case letters 'a' to 'z' for digit values >= 10.
# The most common numeric conversions are Atoi (string to int) and Itoa (int to string). # These assume decimal and the Go int type. i, err := strconv.Atoi("-42") s := strconv.Itoa(-42) # ParseBool, ParseFloat, ParseInt, and ParseUint convert strings to values: b, err := strconv.ParseBool("true") f, err := strconv.ParseFloat("3.1415", 64) i, err := strconv.ParseInt("-42", 10, 64) u, err := strconv.ParseUint("42", 10, 64) # The parse functions return the **widest type (float64, int64, and uint64)**, # but if the size argument specifies a narrower width the result can be # converted to that narrower type without data loss: s := "2147483647" // biggest int32 i64, err := strconv.ParseInt(s, 10, 32) i := int32(i64) # FormatBool, FormatFloat, FormatInt, and FormatUint convert values to strings: s := strconv.FormatBool(true) s := strconv.FormatFloat(3.1415, 'E', -1, 64) s := strconv.FormatInt(-42, 16) s := strconv.FormatUint(42, 16)
The buffer size is the number of elements that can be sent to the channel without the send blocking. By default, a channel has a buffer size of 0 (you get this with make(chan int)). This means that every single send will block until another goroutine receives from the channel. A channel of buffer size 1 can hold 1 element until sending blocks.
package main import "fmt" func main() { // 这是一个单 goroutine 的程序 ch := make(chan int) // buffer size 0 ch <- 1 // 第一个就会报错 // fatal error: all goroutines are asleep - deadlock! // goroutine 1 [chan send] // exit status 2 ch := make(chan int, 1) // buffer size 1 ch <- 1 // 第一个能写入 ch <- 2 // 第二个会报错 // fatal error: all goroutines are asleep - deadlock! // goroutine 1 [chan send] // exit status 2 ch := make(chan int, 2) // buffer size 2,最多能写 2 个 // 写两个读两个正常 ch <- 1 ch <- 2 fmt.Println(<-ch) fmt.Println(<-ch) // 写一个读一个也正常 ch <- 1 ch <- 2 fmt.Println(<-ch) fmt.Println(<-ch) }
package main import "fmt" func fib(c, quit chan int) { x, y := 0, 1 for { // The select statement lets a goroutine wait on // multiple communication operations. // // A select blocks until one of its cases can run, // then it executes that case. It chooses one at // random if multiple are ready. select { case c <- x: x, y = y, x+y case <-quit: fmt.Println("quit") return } } } func main() { c := make(chan int) quit := make(chan int) go func() { for i := 0; i < 10; i++ { fmt.Println(<-c) // 2. goroutine 里写 channel } quit <- 0 // 3. 万一还没运行到 fib 就先写了怎么办? }() fib(c, quit) // 1. 先注册监听 channel }
可能能解答上面的问题
c := make(chan int) // Allocate a channel. // Start the sort in a goroutine; when it completes, signal on the channel. go func() { list.Sort() c <- 1 // Send a signal; value does not matter. }() doSomethingForAWhile() <-c // Wait for sort to finish; discard sent value. // go 应该是 main 运行到底就退出,不管 goroutine