1.//.(type),比如 username.(string)
&:类型断言,是interface{}转string
2..//判断网页中checkbox是否被选中
&:为checkbox添加value属性,后台判断r.FormValue(checkbox的name属性) != "",表示被选中
3.//直接输出HTML
string类型go的template处理时会自动做escape处理,用template.HTML类型就不会了
values := map[string]template.HTML{"html": template.HTML("<br/>")}4.//slice赋值
var a = []string{ "1", "2", } func Do() (c []string) { b := a log.Print(len(b), cap(b))//2,2 len = cap 了,append后将创建新的底层数组 b = append(b, "3") log.Print(len(b), cap(b)) log.Print(b, a) return b } func Do1() (c []string) { b := a //这是引用,b,a指向同一个底层array log.Print(b, a) b[1] = "3" //a同时变化 log.Print(b, a) return b } //slice赋值 func Do2() (c []string) { c = make([]string, 2) //要先声明否则下面赋值时会越界 copy(c, a) log.Print(c, a) c[1] = "2" log.Print(c, a) return c }
slice具体使用可参考http://blog.golang.org/go-slices-usage-and-internals
//select问题
问题1:
messages := make(chan string) signals := make(chan bool) select { case msg := <-messages: fmt.Println("received message", msg) default: fmt.Println("no message received") } msg := "hi" select { case messages <- msg: fmt.Println("sent message", msg) default: fmt.Println("no message sent") } select { case msg := <-messages: fmt.Println("received message", msg) case sig := <-signals: fmt.Println("received signal", sig) default: fmt.Println("no activity") } 不是应该输出: no message received sent messagehi received messagehi 怎么会是: no message received no message sent no activity原因:
默认通道是 无缓冲 的,这意味着只有在对应的接收(<- chan)通道准备好接收时,才允许进行发送(chan <-),即非缓冲通道,没有接收者会阻塞.你可能会问第一个select不是给第二个select提供接受者了吗?其实:第一个 select 里面的 case msg := <-messages 虽然尝试执行,但是由于当时 messages 里面没有数据,所以最后执行的是 default,也就是<- 操作就没有执行,messages 又没有 buffer,所以第二个 select 执行的时候已经没有 goroutine 在接受 messages 里面的数据了,自然没法 send 数据。
第一个 select 可以来理解为: if messages has data to be read { msg := <- messages // execute code after the case statement } else { // default } 当然,上面的代码第一行和第二行是原子的执行的。如果messages当时没有数据,又可以不 block,那么就相当于messages什么也没变化。ps:
channel的receiver和sender需在两个不同的goroutine里,否则会应为阻塞,出现deadlock.
问题2:
ch := make(chan int, 1) for { select { case ch <- 0: case ch <- 1: } i := <-ch fmt.Println("value=", i) } 程序怎么会交替随机输出0和1呢?原因是golang select机制(https://golang.org/ref/spec#Select_statements):
检查每个case语句
如果有任意一个chan是send or recv read,那么就执行该block 如果多个case是ready的,那么随机找1个并执行该block 如果都没有ready,那么就block and wait 如果有default block,而且其他的case都没有ready,就执行该default block问答3:
package main
import "fmt" func main() { jobs := make(chan int, 5) done := make(chan bool) go func() { for { j, more := <-jobs if more { fmt.Println("received job", j) } else { fmt.Println("received all jobs") done <- true return } } }() for j := 1; j <= 3; j++ { jobs <- j fmt.Println("sent job", j) } close(jobs) fmt.Println("sent all jobs") <-done }关闭的channel仍可读取?channel特性:一个已经被关闭的 channel 永远都不会阻塞,但不能再向这个 channel 发送数据,不过仍然可以尝试从 channel 中获取值,直至读完剩余数据,而后才开始返回对应channel类型的零值.
参考:绝妙的 channel#http://blog.csdn.net/kjfcpua/article/details/18263839
//timer
<-timer.C 是直到这个定时器Stop()之前,将一直阻塞,除非timer时间到期接收到了新的数据(Time),即timer过期.
//syscall.Exec 参数疑问
syscall.Exec(binary, args, env)中的args其实只用到了args[1:],即args[0]会被忽略
//url encode
url.QueryEscape("我爱golang")
//无缓冲channel,先要有读否则写阻塞
N:=time.Duration(0) //尝试修改N的值,看结果
messages := make(chan string) go func() { messages <- "ping" println(1)}() time.Sleep(N*time.Second) msg := <-messages fmt.Println(msg)获取上传文件大小:
下面的大小文件是针对存放数据的缓冲区而言.
// 获取文件大小的接口,for 小文件保存在内存中 type Size interface { Size() int64 } // 获取文件信息的接口,for 大文件,在虚拟内存中 type Stat interface { Stat() (os.FileInfo, error) } if statInterface, ok := file.(Stat); ok { fileInfo, _ := statInterface.Stat() fmt.Fprintf(w, "上传文件的大小为: %d", fileInfo.Size()) } if sizeInterface, ok := file.(Size); ok { fmt.Fprintf(w, "上传文件的大小为: %d", sizeInterface.Size()) }
//new
new(T)会为T类型分配内存,其值为零值,并且返回它的地址;想同时初始化可用&T.
精彩评论