вызвать функцию, которая принимает "chan interface {}" - PullRequest
0 голосов
/ 03 апреля 2019

Для людей, которые проголосовали за этот вопрос - у него есть законный ответ, который является отражением (см. Ниже).

Я хочу создать универсальную функцию, в которой я могу передать ему любой канал, и он сообщит мне, сколько его емкости заполнено.Я нахожу это раздражающим, что я должен привести канал к "chan interface {}".

Мой вопрос: для функции foo ниже я могу передать ей строку, и это нормально.Go принимает это как интерфейс {}.Почему он не ведет себя одинаково для каналов?Могу ли я создать функцию, которая принимает общий chan interface{}?

func testFoo() {
    str := "anything"
    foo(str)  //This is fine.
    aChan := make(chan string, 10)

    //This line doesn't compile.  Can I avoid casting to chan interface{}?
    CheckChanLen(aChan) 
}

func foo(obj interface{}) {}

func CheckChanLen(aChan chan interface{}) {
    chanCap := cap(aChan)
    chanLen := len(aChan)
    fmt.Printf("len:%d cap:%d", chanLen, chanCap)
}

1 Ответ

2 голосов
/ 03 апреля 2019

Краткий ответ: нет.

chan interface{} отличается от interface{}.

interface{} является универсальным для всех типов, но chan interface{} является НЕ универсальное решение для всех типов chan.

Универсальные функции предоставят эту возможность, но они не на языке go ( пока ).


Если все, что вам нужно сделать, это проверить емкость / длину канала, вы можете использовать пакет reflect следующим образом:

import "reflect"

func CheckChanLen(aChan interface{}) {
        rv := reflect.ValueOf(aChan)
        if rk := rv.Kind(); rk != reflect.Chan {
                panic("expecting type: 'chan ...'  instead got: " + rk.String())
        }           

        chanCap := rv.Cap()
        chanLen := rv.Len()
        fmt.Printf("len:%d cap:%d\n", chanLen, chanCap)
}
...