This question already has answers here:
How can I instantiate a non-nil pointer of type argument with generic Go?
(4 answers)
What is the generic type for a pointer that implements an interface?
(2 answers)
Closed 9 months ago.
I have a generic func func foo[T bar]() which I need to pass a type which is a pointer to a struct foo[*zab](). In func foo I want to initialize the value using one of new() or var t T.
My question is if that is possible and if, how! See the code below (with link to Go playground):
package main
import "fmt"
func main() {
foo[*zab]()
}
type bar interface {
String() string
SetString(string)
}
func foo[T bar]() {
var t T
t.SetString("asdf")
fmt.Println(t.String()) // Should return "asdf"
}
type zab struct {
f string
}
func (z zab) String() string {
return z.f
}
func (z *zab) SetString(f string) {
z.f = f
}
https://go.dev/play/p/rLCuvYNem1t
Related
This question already has answers here:
How do contravariant types work in golang 1.18 with generics?
(1 answer)
How to implement generic interfaces?
(2 answers)
Closed 5 months ago.
In the below example, WK8Map implements OrderedMap:
type OrderedMap interface {
Get(string) string
}
type WK8Map struct {
value *orderedmap.OrderedMap[string, string]
}
func (m *WK8Map) Get(key string) string {
return ""
}
However, the moment I introduce generics, my IDE GoLand says that WK8Map no longer implements OrderedMap:
type OrderedMap[K comparable, V any] interface {
Get(K) V
}
type WK8Map[K comparable, V any] struct {
value *orderedmap.OrderedMap[K, V]
}
func (m *WK8Map[K, V]) Get(key K) V {
value, _ := m.value.Get(key)
return value
}
Why does my attempt at implementing the generic interface fail?
This question already has answers here:
How can I access a struct field with generics (type T has no field or method)?
(1 answer)
In Go generics, how to use a common method for types in a union constraint?
(3 answers)
Closed 9 months ago.
I'm somewhat new to Golang but very new to 1.18 generics.
I have two compile-time errors in the following program and can't figure out how to get it working.
Any help would be greatly appreciated.
package main
import (
"database/sql"
)
type SeriesType interface {
sql.NullTime | sql.NullInt64 | sql.NullFloat64 | sql.NullString
}
type Series[T SeriesType] struct {
Name string
Values []T
}
func NewSeries[T SeriesType](name string) Series[T] {
s := Series[T]{Name: name, Values: make([]T, 0)}
return s
}
func (s *Series[T]) Append(e any) error {
var t T //T = sql.NullInt64 so t is a struct of type sql.NullInt64
t.Scan(e) //***** compile error: t.Scan undefined (type T has no field or method Scan)
s.Values = append(s.Values)
return nil
}
func (s *Series[T]) Print() {
for i := range s.Values {
println(s.Values[i].Int64) //**** compile error: s.Values[i].Int64 undefined (type T has no field or method Int64)
}
}
func main() {
s := NewSeries[sql.NullInt64]("test")
s.Name = "newTest"
println(s.Name) //prints "newTest"
s.Append(1)
s.Print()
}
This question already has answers here:
Is unnamed arguments a thing in Go?
(3 answers)
Closed 1 year ago.
the code
package main
import "fmt"
type unimplementedGreeterServer struct {
}
func (unimplementedGreeterServer) SayHello() string {
return "hello"
}
func main() {
s := &unimplementedGreeterServer{}
ret := s.SayHello()
fmt.Println(ret)
}
the result
hello
the question :
why the SayHello method has no unimplementedGreeterServer point or unimplementedGreeterServer receiver can run
I think the right will be
func (s unimplementedGreeterServer) SayHello2() string {
return "hello"
}
func (s *unimplementedGreeterServer) SayHello3() string {
return "hello"
}
not
func (unimplementedGreeterServer) SayHello() string {
return "hello"
}
The receiver itself is optional. If the method does not use the receiver, you can omit it. The declaration:
func (unimplementedGreeterServer) SayHello() string {
return "hello"
}
simply defines a method for unimplementedGreeterServer that does not use the receiver. It is defined for a value receiver, so it is defined for unimplementedGreeterServer and *unimplementedGreeterServer.
This question already has answers here:
Type converting slices of interfaces
(9 answers)
Closed 4 years ago.
code:
package main
import "fmt"
type implementation struct {
d []int
}
func (impl *implementation) getData() interface{} {
return impl.d
}
type phase struct{}
type data interface {
getData() interface{}
}
func MakeIntDataPhase() *phase {
return &phase{}
}
func (p *phase) run(population []data) []data {
return nil
}
func main() {
var population []implementation
MyPhase := MakeIntDataPhase()
fmt.Println(MyPhase.run(population))
}
When running following code in playground I got following error: prog.go:30:25: cannot use population (type []implementation) as type []data in argument to MyPhase.run
I am new to golang and I don't understand why is this happening?
Struct implementation implements method getData() from data interface. Isn't it enough to use a slice of implementation in run method?
Where my reasoning is wrong?
This seems counter-intuitive but []data is of a different type to []implementation because of how slice types are represented in Go.
This is actually discussed in the the Go Wiki
Edit: Consider this
var impl []*implementation
var data []data = impl
The compiler will complain with
cannot use impl (type []*implementation) as type []data in assignment
It's more code but you actually have to create a slice of your interface as what the comments in this thread recommends, like so:
var impl []*implementation
var data []data
// assuming impl already has values
for _, v := range impl {
data = append(data, v)
}
This question already has answers here:
slice of struct != slice of interface it implements?
(6 answers)
Closed 5 years ago.
I want to call a method which accepts slice of interface as paramers in golang, but I find that I cannot pass it write as this:
type Base interface {
Run()
}
type A struct {
name string
}
func (a *A) Run() {
fmt.Printf("%s is running\n", a.name)
}
func foo1(b Base) {
b.Run()
}
func foo2(s []Base) {
for _, b := range s {
b.Run()
}
}
func TestInterface(t *testing.T) {
dog := &A{name: "a dog"}
foo1(dog)
// cat := A{name: "a cat"}
// foo1(cat)
s := []*A{dog}
foo2(s)
}
I get error like this:
cannot use s (type []*A) as type []Base in argument to foo2
If the function takes a []Base parameter, you must pass a []Base parameter. Not a []interface{}, not a []thingThatImplementsBase, but specifically a []Base. A slice of interfaces isn't an interface - it isn't "implemented by" a slice of any other type. The elements of a slice of interfaces can be anything that implements the interface, but the slice itself is of a strict and specific type.