I guess I didn't ask an actual question... is there a more idiomatic way of doing this?
Thank you! -- Salvatore smile. On Monday, July 24, 2023 at 4:00:59 PM UTC-4 Salvatore Domenick Desiano wrote: > Ever since 1.18 came out I've been struggling to find an idiomatic way to > implement a certain kind of adapter. I'm starting to suspect I'm Holding It > Wrong (TM) so here I am. > > In short, I have an adapter that is effectively a collection of static > methods and it doesn't look right. > > Imagine you have a generic key-value database (transaction and life-cycle > methods omitted for brevity): > > type SimpleDatabase interface { > Get(t ViewTransaction, key string) ([]byte, bool, error) > Put(t UpdateTransaction, key string, value []byte) error > } > > You then want to build something more specific on top using generics to > avoid repetition of tricky code: > > type ApplicationDatabase struct { > impl *SimpleDatabase > } > > func (db *ApplicationDatabase) PutProjectRecord(t UpdateTransaction, r > *ProjectRecord) error { > return put[ProjectRecord](db.impl, projectRecordFactory, t, r) > } > > type recordFactory[V any] interface { > dbKey(value V) string > encodeValue(value V) []byte > decodeValue(data []byte) (V, error) > } > > func put[V any](db *SimpleDatabase, f *recordFactory[V], t > UpdateTransaction, value V) error { > key := f.dbKey(value) > valueBytes := f.encodeValue(value) > if err := db.put(t, key, valueBytes); err != nil > return fmt.Errorf("db error: %w", err) > } > return nil > } > > This is nice and clean -- adding a new record type is just a matter of > adding a new recordFactory implementation. Adding more complexity to the > put/get (recovery, etc.) only has to happen once. The part that bugs me, > though, is that the implementation has no state and really looks like it > shouldn't be instantiated: > > type projectRecordFactory struct{} > func (f *projectRecordFactory) dbKey() string { return .... } > func (f *projectRecordFactory) encodeValue(value V) []byte { > json.Marshal(...) } > func (f *projectRecordFactory) decodeValue(data []byte) (V, error) { > json.Unmarshal(...) } > > and, frankly, if I didn't instantiate it, it would feel like either Java > or C++ metaprogramming. > > I'm open to a completely different structure but I am really hoping to add > new record types by adding a new package or type. > > Thanks! > > -- Salvatore > smile. > > -- 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+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/318e98c2-d13e-4188-b65b-bbc7644e3ab7n%40googlegroups.com.