Interface récursive en go

a marqué ce sujet comme résolu.

Bonjour,

en m’amusant un peu, je suis tombé sur une erreur qui me pose une colle conceptuelle:

package main

import "fmt"

type Vector interface {
	Add(Vector) Vector
	Scale(float64) Vector
}

type Complex struct {
	Re float64
	Im float64
}

func (z Complex) Add(w Complex) Complex {
	return Complex{
		z.Re + w.Re,
		z.Im + w.Im,
	}
}

func (z Complex) Scale(f float64) Complex {
	return Complex{
		f * z.Re,
		f * z.Im,
	}
}

type Sequence []float64

func (q Sequence) Add(r Sequence) Sequence {
	var sum Sequence

	for i := 0; i < len(q); i++ {
		sum = append(sum, q[i] + r[i])
	}

	return sum
}

func (q Sequence) Scale(f float64) Sequence {
	var scaled Sequence

	for i := 0; i < len(q); i++ {
		scaled = append(scaled, f * q[i])
	}

	return scaled
}

func main() {
	z := Complex{3, 8}
	q := Sequence([]float64{1, 2, 3.14, 7.12, 9.81})

	Print(z) // cannot use z (variable of type Complex) as Vector value in argument to Print: Complex does not implement Vector (wrong type for method Add)
                 // have Add(Complex) Complex
                 // want Add(Vector) Vector

	Print(q) // cannot use q (variable of type Sequence) as Vector value in argument to Print: Sequence does not implement Vector (wrong type for method Add)
                 // have Add(Sequence) Sequence
                 // want Add(Vector) Vector
}

func Print(v Vector) {
	fmt.Println(v)
}

car, par exemple, je ne veux pas avoir func (z Complex) Add(w Vector) Vector puisque je ne veux pas pouvoir additioner les bananes et les poires ! :colere:

Dans mon interface, Vector ne peut-il pas être substitué par Complex ou Sequence puisque ces deux types implémentent justement Vector ?

Comment résoudre ce problème ?

+0 -0

Si je comprends bien, ici le type Vector est récursif, pas générique. Ni Complex, ni Sequence n’implémente Vector car pour implémenter Vector il faut que Add soit défini sur Vector et non sur le type en lui-même.

Ce que tu veux faire c’est de la généricité.

package main

import "fmt"

type Vector[T any] interface {
	Add(T) T
	Scale(float64) T
}

type Complex struct {
	Re float64
	Im float64
}

func (z Complex) Add(w Complex) Complex {
	return Complex{
		z.Re + w.Re,
		z.Im + w.Im,
	}
}

func (z Complex) Scale(f float64) Complex {
	return Complex{
		f * z.Re,
		f * z.Im,
	}
}

type Sequence []float64

func (q Sequence) Add(r Sequence) Sequence {
	var sum Sequence

	for i := 0; i < len(q); i++ {
		sum = append(sum, q[i] + r[i])
	}

	return sum
}

func (q Sequence) Scale(f float64) Sequence {
	var scaled Sequence

	for i := 0; i < len(q); i++ {
		scaled = append(scaled, f * q[i])
	}

	return scaled
}

func main() {
	z := Complex{3, 8}
	q := Sequence([]float64{1, 2, 3.14, 7.12, 9.81})

	Print(z)
	Print(q)}

func Print[T any](v Vector[T]) {
	fmt.Println(v)
}
+1 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte