#Ignored generics for struct field

21 messages · Page 1 of 1 (latest)

sinful atlas
#

is it possible to have a struct field as such, basically with a blank/ignored generic parameter? I want to have iterator behavior inherited, but I don't want the individual iterator types (KeyIterator, ValueIterator) to need to specify the other type which isn't used

type NodeIterator[K, V any] struct { ... }
type KeyIterator[K any] struct {
    // java: NodeIterator<K, ?> (I know, these compile differently)
    iter *NodeIterator[K, any]
}

keyIter := &KeyIterator[string]{
    // compile error due to int != any
    iter: &NodeIterator[string, int]{...}
}
sweet ridge
#

why not just pass any to both?

sinful atlas
#

it all boils down to the TreeMap type, which is kept in NodeIterator to allow things to be removed later on

#
func (t *TreeMap[K, V]) NodeIterator() *NodeIterator[K, V] {
    return &NodeIterator[K, V]{
        treemap: t,
        next:    t.root,
        last:    nil,
    }
}
#
type NodeIterator[K, V any] struct {
    treemap *TreeMap[K, V]
    next    *TreeNode[K, V]
    last    *TreeNode[K, V]
}
#

so unless I were to enforce the TreeMap itself having any keys and values, it'd require on some level that there be a way to blank out the value for one of the iterators, or have both generic params specified in every iterator type

sweet ridge
#

i believe you cant left out, generic type in go. you must specify it, one way or another.
i'm kinda lazy to think rn. other member might be able to help.

warped kiln
#

struct{} should do the trick

#

it's a 0 sized type. You still have to pass it, but it's 0 sized

sinful atlas
#

this?

type KeyIterator[K any] struct {
    iter *NodeIterator[K, struct{}]
}

func (t *TreeMap[K, V]) KeyIterator() *KeyIterator[K] {
    return &KeyIterator[K]{
        iter: t.NodeIterator(),
    }
}

func (t *TreeMap[K, V]) NodeIterator() *NodeIterator[K, V] {
    return &NodeIterator[K, V]{...}
}
```doesn't appear to work
#
./treemap.go:226:9: cannot use t.NodeIterator() (value of type *NodeIterator[K, V]) as type *NodeIterator[K, struct{}] in struct literal
#

my goal is to get the user side looking like this ```go
var tm *treemap.TreeMap[string, int] = treemap.Newstring, int
var kIt *treemap.KeyIterator[string] = tm.KeyIterator()
var vIt *treemap.ValueIterator[int] = tm.ValueIterator()
// ^^^^^^ just the one generic

sweet ridge
#
func (t *TreeMap[K, V]) KeyIterator() *KeyIterator[K] {
    return &KeyIterator[K]{
        iter: t.NodeIterator(),
    }
}

t is *TreeMap[K, V] so t.NodeIterator() would return NodeIterator[K, V]
but KeyIterator is defined as follow

type KeyIterator[K any] struct {
    iter *NodeIterator[K, struct{}]
}

which does not match with the TreeMap

#

can the KeyIterator be an interface? instead of concrete type?

type KeyIterator[K any] interface {
    Iter() K
}
restive hatch
#

This works in java because <string, int> is type erased

#

Go does not do type erasure on the generic types

#

I don’t think it’s actually possible to express the equivelent to [string, any] in java

warped kiln
#

but that's not written in the spec and the compiler doesn't give a f

sinful atlas
#

so I'm satisfied with this if it's not possible to bring the iterator structs themselves down to the single type