Is this a known problem?

106 views
Skip to first unread message

tapi...@gmail.com

unread,
Nov 12, 2021, 9:17:27 AM11/12/21
to golang-nuts

func Bar[T []byte|string](s T) bool {
    for _, v := range s { // cannot range over s (variable of type T constrained by []byte|string) (T has no structural type)
        if v > 100 {
            return true
        }
    }
    return false
}

The message is quite confusing.

Axel Wagner

unread,
Nov 12, 2021, 10:10:17 AM11/12/21
to tapi...@gmail.com, golang-nuts
`range s` works differently for string and []byte. In the former case it iterates over utf8-encoded unicode codepoints, in the latter it iterates over bytes.

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/44b5f535-adc8-4049-ba41-638f90becc3cn%40googlegroups.com.

tapi...@gmail.com

unread,
Nov 12, 2021, 10:28:56 AM11/12/21
to golang-nuts
On Friday, November 12, 2021 at 11:10:17 PM UTC+8 axel.wa...@googlemail.com wrote:
`range s` works differently for string and []byte. In the former case it iterates over utf8-encoded unicode codepoints, in the latter it iterates over bytes.

It is true, but why it matters here?

Axel Wagner

unread,
Nov 12, 2021, 10:40:53 AM11/12/21
to tapi...@gmail.com, golang-nuts
On Fri, Nov 12, 2021 at 4:29 PM tapi...@gmail.com <tapi...@gmail.com> wrote:
On Friday, November 12, 2021 at 11:10:17 PM UTC+8 axel.wa...@googlemail.com wrote:
`range s` works differently for string and []byte. In the former case it iterates over utf8-encoded unicode codepoints, in the latter it iterates over bytes.

It is true, but why it matters here?

Because it makes `range` different operations for the purposes of determining the allowed operations on a type-parameter.
 
 

On Fri, Nov 12, 2021 at 3:18 PM tapi...@gmail.com <tapi...@gmail.com> wrote:

func Bar[T []byte|string](s T) bool {
    for _, v := range s { // cannot range over s (variable of type T constrained by []byte|string) (T has no structural type)
        if v > 100 {
            return true
        }
    }
    return false
}

The message is quite confusing.

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/44b5f535-adc8-4049-ba41-638f90becc3cn%40googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.

tapi...@gmail.com

unread,
Nov 12, 2021, 10:46:39 AM11/12/21
to golang-nuts
This one doesn't compile either.
So the range operation doesn't support values of parameter types?

type MyByte byte

func Bar[T []byte|[]MyByte](s T) {
    for range s {} // cannot range over s (variable of type T constrained by []byte|[]MyByte) (type set has no single underlying
}

Axel Wagner

unread,
Nov 12, 2021, 10:53:34 AM11/12/21
to tapi...@gmail.com, golang-nuts
The error message gives you a reason - there is no single underlying type. This works:

type B []byte
func Bar[T []byte|B](s T) {
    for range s {}
}

But yes, your example arguably should be made to work eventually. I would suggest filing an issue about that.

Axel Wagner

unread,
Nov 12, 2021, 10:54:36 AM11/12/21
to tapi...@gmail.com, golang-nuts
Oh, sorry, I just re-read. Your example still requires `range` to return distinct types, so that probably shouldn't work.

T L

unread,
Nov 12, 2021, 11:08:40 AM11/12/21
to Axel Wagner, golang-nuts
On Fri, Nov 12, 2021 at 11:54 PM Axel Wagner <axel.wa...@googlemail.com> wrote:
Oh, sorry, I just re-read. Your example still requires `range` to return distinct types, so that probably shouldn't work.

Not this reason:

func Bar[T []byte|map[int]byte](s T) {
    for i, v := range s { _, _ = i, v} // cannot range over s (variable of type T constrained by []byte|map[int]byte) (type set has no single underlying type)
}

Axel Wagner

unread,
Nov 12, 2021, 11:37:52 AM11/12/21
to golang-nuts
It is still a different operation. For example, a range over a map is not necessarily deterministic.

If you continue to ask detail-questions like this, it would be useful if you could provide an actual program you'd want to write using them. Otherwise, it makes a lot more sense to just wait for the spec-changes to be known. At that point, it'll be easier to talk about if a specific example does or does not conform to the spec.

Robert Engels

unread,
Nov 12, 2021, 11:42:19 AM11/12/21
to Axel Wagner, golang-nuts
I think all of this will probably be handled with wrapper collections types and the iterator pattern. 

Generics should make this easy. It would be great is range supported this but it seems doubtful. 

On Nov 12, 2021, at 10:37 AM, 'Axel Wagner' via golang-nuts <golan...@googlegroups.com> wrote:


Reply all
Reply to author
Forward
0 new messages