On Fri, 20 Oct 2023 at 07:51, Ian Lance Taylor <i...@golang.org> wrote:
> On Thu, Oct 19, 2023 at 5:14 PM Jason E. Aten <j.e.a...@gmail.com> wrote: > > > > Analogous to > > > > type IntSlice []int > > > > func (p IntSlice) Len() int { return len(p) } > > func (p IntSlice) Less(i, j int) bool { return p[i].val < p[j].val } > > func (p IntSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } > > > > and then calling sort.Sort() on an IntSlice, I figured I > > could create a type that is a new name for an instantiated generic type > and > > then call methods on that new type... but no? > > > > For example: > > https://go.dev/play/p/K5FGtNi6hLM > > > > package main > > > > import "fmt" > > > > type Addable interface { > > ~complex128 | ~complex64 | ~float64 | ~float32 | > > ~byte | ~uint16 | ~uint32 | ~uint64 | > > ~int8 | ~int16 | ~int32 | ~int64 | ~int > > } > > > > type Matrix[T Addable] struct { > > Nrow int > > Ncol int > > Dat []T > > } > > > > func (m *Matrix[T]) Col(j int) (res []T) { > > for i := 0; i < m.Nrow; i++ { > > res = append(res, m.At(i, j)) > > } > > return > > } > > > > // At reads out the [i,j]-th element. > > func (m *Matrix[T]) At(i, j int) T { > > return m.Dat[i*m.Ncol+j] > > } > > > > func main() { > > m := &Matrix[float64]{ > > Nrow: 2, > > Ncol: 3, > > Dat: make([]float64, 2*3), > > } > > fmt.Printf("m.At(1,2) = '%v'", m.At(1, 2)) // this is fine, of course. > > } > > > > // I assumed this would work... but go 1.21 rejects the call to At() > below. > > type MatrixF64 Matrix[float64] > > > > func UseMatrixF64(m *MatrixF64) { > > // so why won't this compile? if the same line in main() works? > > fmt.Printf("m.At(1,2) = '%v'", m.At(1, 2)) // compile error: m.At > undefined (type *MatrixF64 has no field or method At) > > } > > Using "type MatrixF64 ..." defines a new type that doesn't inherit any > of the method of the old type. That's how type definitions work in > Go. It will work as you expect if you use a type alias: "type > MatrixF64 = ...". > > Ian > > -- > 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/CAOyqgcUKo1n3BY5z1OWSFR4omZX4gFXpCgHg5%2BbHrb3jsk7E0w%40mail.gmail.com > . > There are two ways to enable this, which are worth discussing further as of why Go decided to behave this way. 1. To use type alias as mentioned before `type MatrixF64 = Matrix[float64]`, this is generally works but unfortunately, doesn't worth it in the case of aliasing primitives type, i.e. `type String = string` won't allow you to bind new methods to `String` unlike `type String string`. I would like to know why. 2. To use type embedding such as: type MatrixF64 struct { Matrix[float64] }, since struct/interface embedding will allow the parent struct to call embedded methods/fields directly. Again, I would love to see the motivation between these design decisions, pretty much I would like to allow new methods to be attached to type primitives without resorting to manual type casting / type assertion, but that's another topic. Regards. -- regards, Nurahmadie -- -- 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/CA%2BcQEWFRZJ8dN_YBo5qjvZ0cpijxGJikz5qws0ToUQa_OMaPDA%40mail.gmail.com.