go 的select必须要for{}吗

yaxiaomu · 2020-05-08 18:15:32 · 1508 次点击 · 大约8小时之前 开始浏览    置顶
这是一个创建于 2020-05-08 18:15:32 的主题,其中的信息可能已经有所发展或是发生改变。

如题,另外以下三段有什么区别吗,哪个性能上更好?怎么分析一下

第一段

ch := make(chan string, 10)
    go func() {
        for i := 0; i < 10; i++ {
            fmt.Println("input ", i)
            ch <- strconv.Itoa(i)
        }
    }()
    go func() {
    LOOP:
        for {
            select {
            case m1 := <-ch:
                println("m1", m1)
            default:
                break  LOOP
            }
        }
    }()

第二段

    go func() {
        for i := 0; i < 10; i++ {
            fmt.Println("input ", i)
            ch <- strconv.Itoa(i)
        }
    }()
    go func() {
    LOOP:
        for {
            select {
            case m1 := <-ch:
                println("m1", m1)
            default:
                goto  LOOP
            }
        }
    }()

第三段

    ch := make(chan string, 10)

    go func() {
        for i := 0; i < 10; i++ {
            fmt.Println("input ", i)
            ch <- strconv.Itoa(i)
        }
    }()
    go func() {
        for {
            select {
            case m1 := <-ch:
                println("m1", m1)
            default:
            }
        }
    }()

有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1508 次点击  
加入收藏 微博
10 回复  |  直到 2020-05-09 19:13:08
zhengkeyu
zhengkeyu · #1 · 5年之前

你自己没有运行看看吗 问题多多啊

jarlyyn
jarlyyn · #2 · 5年之前

select当然不需要for配合啊,

最典型的例子。

你需要执行一个任务,又需要能在超时时做一些额外处理。

你那3个自立和效率没关系,功能都不一样

yaxiaomu
yaxiaomu · #3 · 5年之前
jarlyynjarlyyn #2 回复

select当然不需要for配合啊, 最典型的例子。 你需要执行一个任务,又需要能在超时时做一些额外处理。 你那3个自立和效率没关系,功能都不一样

我的理解既然用了select,就是要针对多个不同的channel做收发item操作。如果不for,select一次就退出了,那还有什么意义呢

yaxiaomu
yaxiaomu · #4 · 5年之前
zhengkeyuzhengkeyu #1 回复

你自己没有运行看看吗 问题多多啊

比如呢

jarlyyn
jarlyyn · #5 · 5年之前
yaxiaomuyaxiaomu #3 回复

#2楼 @jarlyyn 我的理解既然用了select,就是要针对多个不同的channel做收发item操作。如果不for,select一次就退出了,那还有什么意义呢

for和不同channel的收发操作有什么关系……

for是保证常驻,多次处理啊啊。

举个例子。

你现在需要进行一次查询,从5个数据源中取得数据,只需要有任何一个数据源取得信息就进行下一步处理,这时候就不需要for啊

再举个自立。

你现在需要做一个服务的关闭处理,就是接受退出信号后,退出服务并执行一段代码,然后退出代码只执行一次,退出信号又有多个来源。

yaxiaomu
yaxiaomu · #6 · 5年之前
jarlyynjarlyyn #5 回复

#3楼 @yaxiaomu for和不同channel的收发操作有什么关系…… for是保证常驻,多次处理啊啊。 举个例子。 你现在需要进行一次查询,从5个数据源中取得数据,只需要有任何一个数据源取得信息就进行下一步处理,这时候就不需要for啊 再举个自立。 你现在需要做一个服务的关闭处理,就是接受退出信号后,退出服务并执行一段代码,然后退出代码只执行一次,退出信号又有多个来源。

嗯,谢谢,你这两个场景我理解,是没有必然联系。 有一些场景比如要通过channel监听心跳,或者针对不同的chan过来的数据进行不同的处理,这些就需要了。 另外有时间帮忙看看这个问题^_^:https://studygolang.com/topics/11434

zhengkeyu
zhengkeyu · #7 · 5年之前
yaxiaomuyaxiaomu #4 回复

#1楼 @zhengkeyu 比如呢

第一段:有可能一个channel都读不到就break loop 了 第二段: goto loop是多余的

lpflpf
lpflpf · #8 · 5年之前

3楼 @yaxiaomu 一个简单的例子:

官方提供的database/sql.go 文件中的代码

func (db *DB) conn(ctx context.Context, strategy connReuseStrategy) (*driverConn, error) {
    db.mu.Lock()
    if db.closed {
        db.mu.Unlock()
        return nil, errDBClosed
    }
    // Check if the context is expired.
    select {
    default:
    case <-ctx.Done():
        db.mu.Unlock()
        return nil, ctx.Err()
    }
    lifetime := db.maxLifetime
       // ... balabala
}
yaxiaomu
yaxiaomu · #9 · 5年之前
zhengkeyuzhengkeyu #7 回复

#4楼 @yaxiaomu 第一段:有可能一个channel都读不到就break loop 了 第二段: goto loop是多余的

嗯,谢谢回复~

yaxiaomu
yaxiaomu · #10 · 5年之前
lpflpflpflpf #8 回复

3楼 @yaxiaomu 一个简单的例子: 官方提供的database/sql.go 文件中的代码 ``` func (db *DB) conn(ctx context.Context, strategy connReuseStrategy) (*driverConn, error) { db.mu.Lock() if db.closed { db.mu.Unlock() return nil, errDBClosed } // Check if the context is expired. select { default: case <-ctx.Done(): db.mu.Unlock() return nil, ctx.Err() } lifetime := db.maxLifetime // ... balabala } ```

嗯,理解了,这两个没有必然关系,我是先入为主了。

添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传