请问这个 if else 哪里不对了

2021-03-07 15:52:39 +08:00
 yagamil

刚刚入门,写了个通道不断收发的实例,不过说语法不对。

package main
import "fmt"
import "time"
func sender(ch chan int){
    for i:=0;i<100;i++{
        ch<-i
        time.Sleep(time.MillSecond)
        //ch<-i+1
    }
}

func main() {

    ch:=make(chan int)
    go sender(ch)

    for {
        data,ok:=<-ch
        if ok!=nil {
            fmt.Println("data=",data)

            if data==50 {
                break
            }

       }

        else {
        fmt.Println("No data")
        }
    }

    fmt.Println("Done")
}


把这个注释了就能正常运行: else { fmt.Println("No data") }

2799 次点击
所在节点    Go 编程语言
20 条回复
imdong
2021-03-07 15:53:28 +08:00
这里不对。不能这样写。
yagamil
2021-03-07 15:56:51 +08:00
@imdong 大佬请指教
imdong
2021-03-07 15:58:46 +08:00
好嘛,抖个机灵的功夫帖子编辑了,这回得硬着头皮来解答了...

你等我半小时,我去现学 golang 装好环境再来装逼...
yagamil
2021-03-07 16:02:39 +08:00
@imdong docker 呀
jasonkayzk
2021-03-07 16:03:56 +08:00
channel 返回的第二个参数是 bool 类型,不能和 nil 比较;

把 if ok!=nil 改成 if !ok 就可以运行了;

(代码逻辑没看,只看了语法错误)
yagamil
2021-03-07 16:10:21 +08:00
@jasonkayzk 两个写法都可以,我最开始也是用的!ok,也报 else 的错,用!=nil 也还是包 else 那里的错
zhoudaiyu
2021-03-07 16:17:50 +08:00
![image.png]( https://i.loli.net/2021/03/07/joyYVbAOM8eI3cW.png)

1 、毫秒拼错了
2 、else 网上挪放在 if 右括号右边
jasonkayzk
2021-03-07 16:22:51 +08:00
@yagamil

1.必须使用 !ok,channel 返回的是 bool 类型,不是指针,你怎么能和 nil 比较?
2.Golang 要求 else 必须在 if 右括号右边,不可另起一行,美其名曰:“优雅”
mango88
2021-03-07 16:23:12 +08:00
else 要跟 if 右括号 在一行
jasonkayzk
2021-03-07 16:24:51 +08:00
用 IDE 来给代码 format 啊喂!
yagamil
2021-03-07 16:32:38 +08:00
@jasonkayzk 谢谢大佬,就是那个 else 的括号问题。
初学没用 ide,用 vim 撸的
谢谢大神
zhoudaiyu
2021-03-07 16:35:34 +08:00
另外这个程序会死锁,哪位大神讲讲啊,我不是搞 go 的
yagamil
2021-03-07 16:45:18 +08:00
@zhoudaiyu 把 if ok!=nil 改为 if ok ,data==99 就不会死锁
jasonkayzk
2021-03-07 16:45:26 +08:00
@zhoudaiyu

他的代码写反了,应该是:if ok,如果存在数据;

所以死锁是因为原来的代码仅仅在新的 goroutine 中调用了一次 sender(ch),但是下面的代码是死循环的 for ;
上面调用 sender(ch)的 goroutine 结束后,程序只剩下一个 for,最终 goroutine 渴死;

下面的代码就没问题了;

```go

package main

import (
"fmt"
"time"
)

func sender(ch chan int) {
for i := 0; i < 100; i++ {
ch <- i
time.Sleep(time.Millisecond)
//ch<-i+1
}
}

func main() {
ch := make(chan int)

go sender(ch)

for {
data, ok := <-ch
if ok {
fmt.Println("data=", data)
if data == 50 {
break
}
} else {
fmt.Println("No data")
}
}

fmt.Println("Done")
}
```
zhoudaiyu
2021-03-07 16:49:14 +08:00
@jasonkayzk 啊啊啊啊啊 没注意看写反了 十分感谢您的代码
catcn
2021-03-07 17:21:58 +08:00
vs code 大法啊,vim 插件,golang 插件,妥妥的。
no1xsyzy
2021-03-08 12:47:41 +08:00
@jasonkayzk 说实话,golang 对于 IDE 的需求不是那么大(不如 Java,Java 手动控制目录、导入等等要晕死;甚至不如 Python,Python 几乎所有错误都在运行时,并且错误提示根本没有任何启发性)
实际使用中优雅不见得,no distraction 倒是真的。

@yagamil 不会死锁,是死循环了吧。
no1xsyzy
2021-03-08 12:48:27 +08:00
哦我没发现 sender 是有限循环(
ji39
2021-03-08 16:55:19 +08:00
怎么应用在下载网页,谁给个例子
cominghome
2021-03-16 17:58:37 +08:00
刚学的话还是下个 IDE 吧,能省不少事。上学学 C 的时候没被 include 坑过吗?

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/759301

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX