如何在单个case语句中使用多个表达式?

huangapple go评论78阅读模式
英文:

How to use multiple expressions in single case statement?

问题

在下面的代码中:

package main

import (
    "fmt"
    "reflect"
)

type Model1 struct {
    ID string
}
type Model2 struct {
    ID string
}

func main() {
    ch1 := make(chan Model1)
    close(ch1)
    checkIfChannelClosed(ch1)
    ch2 := make(chan Model2)
    close(ch2)
    checkIfChannelClosed(ch2)

}

func checkIfChannelClosed(ch interface{}) bool {

    if reflect.TypeOf(ch).Kind() != reflect.Chan {

        fmt.Println("只有通道可以关闭")
        return false
    }
    ok := true
    if ch == nil {
        return false
    }

    switch v := ch.(type) {
    case chan Model1:
        select {
        case _, ok = <-v: // Line 26
        default:
        }
    case chan Model2:
        select {
        case _, ok = <-v:
        default:
        }
    default:
        fmt.Println("无效的情况")
    }

    if ok {
        fmt.Println("通道是打开的")
    } else {
        fmt.Println("通道已关闭")
    }
    return ok
}

GoLang编译器不允许在case语句中写入多个表达式(如下所示)。目标是避免为select编写冗余代码:

switch v := ch.(type) {
case chan Model1, chan Model2:
    select {
    case _, ok = <-v:
    default:
    }
default:
    fmt.Println("无效的情况")
}

如何在case语句中使用多个表达式?

英文:

In the below code:

package main

import (
    &quot;fmt&quot;
    &quot;reflect&quot;
)

type Model1 struct {
    ID string
}
type Model2 struct {
    ID string
}

func main() {
    ch1 := make(chan Model1)
    close(ch1)
    checkIfChannelClosed(ch1)
    ch2 := make(chan Model2)
    close(ch2)
    checkIfChannelClosed(ch2)

}

func checkIfChannelClosed(ch interface{}) bool {

    if reflect.TypeOf(ch).Kind() != reflect.Chan {

        fmt.Println(&quot;only channels can be closed&quot;)
        return false
    }
    ok := true
    if ch == nil {
        return false
    }

    switch v := ch.(type) {
    case chan Model1:
        select {
        case _, ok = &lt;-v: // Line 26
        default:
        }
    case chan Model2:
        select {
        case _, ok = &lt;-v:
        default:
        }
    default:
        fmt.Println(&quot;Invalid case&quot;)
    }

    if ok {
        fmt.Println(&quot;channel is open&quot;)
    } else {
        fmt.Println(&quot;channel is closed&quot;)
    }
    return ok
}

GoLang compiler does not allow to write multiple expressions in case statement(as shown below). Goal is to avoid redundant code for select:

switch v := ch.(type) {
case chan Model1, chan Model2:
    select {
    case _, ok = &lt;-v:
    default:
    }
default:
    fmt.Println(&quot;Invalid case&quot;)
}

How to use multiple expressions with case statement?

答案1

得分: 1

我在《The Go programming language》的第7.13章节中读到了这段内容:

在这种风格中,重点是满足接口的具体类型,而不是接口的方法(如果有的话),并且没有隐藏信息。

所以,我认为x.(Type)返回的是一个具体类型。如果你在switch语句中使用多个case并且使用x:=x.(Type),在下面的代码中会发生什么?

switch v := ch.(type) {
case chan Model1,int:
    //做一些操作
}

只需使用reflect.value来完成这个操作:

func checkIfChannelClosed(ch interface{}) bool {
    v := reflect.ValueOf(ch)
    if v.Kind() != reflect.Chan {
	    fmt.Println("只有通道可以关闭")
	    return false
    }

    _, ok := v.TryRecv()
    if ok{
	    fmt.Println("从通道接收到值..")
    }else{
	    fmt.Println("通道已关闭或接收无法完成而不阻塞")
    }

    return ok
}
英文:

I read this in "The Go programming language" chapter 7.13:

In this style, the emphasis is on the concrete types that satisfy the interface, not on the interface’s methods (if indeed it has any),and there is no hiding of information.

So, i think x.(Type) return a concrete type,if you use a multicase in a swith x:=x.(Type), what happend in the follow code?

switch v := ch.(type) {
case chan Model1,int:
    //do something
}

just use the reflect.value to do this:

func checkIfChannelClosed(ch interface{}) bool {
    v := reflect.ValueOf(ch)
    if v.Kind() != reflect.Chan {
	    fmt.Println(&quot;only channels can be closed&quot;)
	    return false
    }

    _, ok := v.TryRecv()
    if ok{
	    fmt.Println(&quot;recv value from channel..&quot;)
    }else{
	    fmt.Println(&quot;channel is closed or receive cannot finish without blocking&quot;)
    }

    return ok
}

huangapple
  • 本文由 发表于 2021年12月20日 09:44:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/70416653.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定