Home > Backend Development > Golang > Generic functions that accept channels and slices

Generic functions that accept channels and slices

PHPz
Release: 2024-02-06 08:36:10
forward
818 people have browsed it

Generic functions that accept channels and slices

Question content

I am trying to write a generic function in golang that will search for values ​​in slices and channels in a similar way. Here is an example:

// minof returns the smallest number found among the channel / slice contents
func minof[t chan int | []int](input t) (result int) {
    for _, value := range input {
        if result > value {
            result = value
        }
    }

    return
}
Copy after login

But I get the following compilation error: cannot range over input (Variable of type t is bound by chan int|[]int) (t has no core type) .

I try to create a generic interface like this:

type Rangable interface {
    chan int | []int
}

// MinOf returns the smallest number found among the channel / slice contents
func MinOf[T Rangable](input T) (result int) {
    for _, value := range input {
        if result > value {
            result = value
        }
    }

    return
}
Copy after login

Although, the error has been changed to cannot range over input (variable of type t subject to rangable) (t has no core type) It remains basically the same...

Is there any way to solve this task using generics or channels and the slice cannot be "converted" to the same core type?

Thank you for any suggestions and ideas!


Correct answer


You can't do that.

range The expression must begin with a core type. Unions with terms of different types have no core type because there is no common underlying type.

You can also intuitively see why

range requires a core type: the semantics of slice and channel ranges are different.

  1. Ranging on a channel may be a blocking operation, ranging on a slice is not

  2. Iteration variables are different

  3. for i, item := range someslice {}
    Copy after login
For slices,

i is an index of type int and item is the type of the slice element.

for item := range somechan {}
Copy after login

For channels,

item is the type of the chan element, and this is the only possible scope variable.

The best you can have is a type switch:

func MinOf[T any, U chan T | []T](input U) (result int) {
    switch t := any(input).(type) {
    case chan T:
        // range over chan
    case []T:
        // range over slice
    }
    return
}
Copy after login
But again, the behavior of this function (blocking vs. non-blocking) depends on the type, and it's not clear what advantage you can gain by using generics here.

The above is the detailed content of Generic functions that accept channels and slices. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:stackoverflow.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template