• GopherChina 社区发布新版了 at 2020年03月19日

    新版社区还是 php 的吗

  • 拉取时怎么办,指定地址吗?

  • git pull卡在Unpacking objects at 2018年11月22日

    拉下来了,用了将近 20 分钟,为什么这么慢?

  • ipfs建站有人做过吗? at 2018年05月08日

    有个问题,ipfs 私有存储的话不会泄露吗,毕竟知道 hash,就能拿到文件

  • 同一端口不行吗?比如都是 80 或 443

  • 可能我直接说,大家不太明白。举个例子:

    package main
    import (
    var mapchan map[string]chan string
    func main() {
        mapchan = make(map[string]chan string)
        mapchan["a"] = make(chan string, 10)
        mapchan["a"] <- "a"
        defer close(mapchan["a"])
        mapchan["b"] = make(chan string, 10)
        mapchan["b"] <- "b"
        defer close(mapchan["b"])

    map 中的 chan string 我只能在 map[string] 中的 string 确定后,再把 chan string 一个一个的 make 成带 buffer 的,有没有办法一开始就初始化好

  • 楼上好像没明白我的意思,请看以一下我三楼的回答 “我现在的解决办法是在 map[string] 的 string 确定后再初始化后面的 chan string。有没有办法一开始就把 chan string 初始化了” 我不是要给它传一个带 buffer 的 chan string,我是直接给它传 string 的

  • 为何说没有意义呢?如果传给 chan string 的量超过一个不就阻塞了吗,如果有 buffer 可以缓冲,不至于阻塞呀

  • 类型是没变,但是初始化成有缓冲的是我的业务需要。我现在的解决办法是在 map[string] 的 string 确定后再初始化后面的 chan string。有没有办法一开始就把 chan string 初始化了

  • 有完整源码吗?可以分享一下吗?

  • 关键你要理解下面的结构的意思

    type ConcurrentEngine struct {
        Scheduler   Scheduler
        WorkerCount int
    type Scheduler interface {
        ConfigurMasterWorkerChan(chan Request)

    ConcurrentEngine 中定义了一个 Scheduler 接口类型的字段,估计你是接口这块没有理解。见意你看一下 go 接口这方面的资料。

    e := engine.ConcurrentEngine{
            Scheduler:&scheduler.SimpleScheduler{}, // 这里为什么要用取地址?

    上面这段赋值过程,SimpleScheduler 实现了 ConcurrentEngine 中的 Scheduler 接口。

     in := make(chan Request)
        out := make(chan ParseResult)
    e.Scheduler.ConfigurMasterWorkerChan(in) //  这一句话看了很久,一直不懂是什么意思
    func (s *SimpleScheduler) ConfigurMasterWorkerChan(c chan engine.Request){
        //  这里给workeChan 赋值不懂是为什么
        s.workerChan = c

    上面这两段的意义就是创建一个 chan 变量,workerChan 在使用前一定要 make 一下,否则不能用的。

  • 首字母大写

  • 常用 time.Format("2006-01-02 15:04:05")

  • type slisli struct {
        a float64 `json:"a"`
        b float64 `json:"b"`
        c string `json:"c"`

    a,b,c 改为大写

  • 看了一下 dialer.Dial("tcp", c.addr) 方法的内部实现,经过层层跳转,确实是返回了*net.Tcp 类型的数据。 最终跳到的函数是:

    func dialTCP(ctx context.Context, net string, laddr, raddr *TCPAddr) (*TCPConn, error) {
        if testHookDialTCP != nil {
            return testHookDialTCP(ctx, net, laddr, raddr)
        return doDialTCP(ctx, net, laddr, raddr)
    func doDialTCP(ctx context.Context, net string, laddr, raddr *TCPAddr) (*TCPConn, error) {
        fd, err := internetSocket(ctx, net, laddr, raddr, syscall.SOCK_STREAM, 0, "dial")
        // TCP has a rarely used mechanism called a 'simultaneous connection' in
        // which Dial("tcp", addr1, addr2) run on the machine at addr1 can
        // connect to a simultaneous Dial("tcp", addr2, addr1) run on the machine
        // at addr2, without either machine executing Listen. If laddr == nil,
        // it means we want the kernel to pick an appropriate originating local
        // address. Some Linux kernels cycle blindly through a fixed range of
        // local ports, regardless of destination port. If a kernel happens to
        // pick local port 50001 as the source for a Dial("tcp", "", "localhost:50001"),
        // then the Dial will succeed, having simultaneously connected to itself.
        // This can only happen when we are letting the kernel pick a port (laddr == nil)
        // and when there is no listener for the destination address.
        // It's hard to argue this is anything other than a kernel bug. If we
        // see this happen, rather than expose the buggy effect to users, we
        // close the fd and try again. If it happens twice more, we relent and
        // use the result. See also:
        //  https://golang.org/issue/2690
        //  http://stackoverflow.com/questions/4949858/
        // The opposite can also happen: if we ask the kernel to pick an appropriate
        // originating local address, sometimes it picks one that is already in use.
        // So if the error is EADDRNOTAVAIL, we have to try again too, just for
        // a different reason.
        // The kernel socket code is no doubt enjoying watching us squirm.
        for i := 0; i < 2 && (laddr == nil || laddr.Port == 0) && (selfConnect(fd, err) || spuriousENOTAVAIL(err)); i++ {
            if err == nil {
            fd, err = internetSocket(ctx, net, laddr, raddr, syscall.SOCK_STREAM, 0, "dial")
        if err != nil {
            return nil, err
        return newTCPConn(fd), nil

    但我现在疑惑的是 Conn 接口是非空接口,*net.Tcp 要实现这个接口必须得有相同的方法吧,但是我好想没看到有相同的方法。

  • 谢谢楼上回复,那我要打印结构体怎么办呢?