Faire une fonction pour une classe et ses sous classes en Kotlin

Salut ! Je suis en train de me faire une petite lib mathématique en kotlin mais j'ai un problème: J'ai définit une classe Matrice qui est en gros une liste a deux dimentions. Je fait en suite une classe MatriceLigne pour une matrice a une seule ligne et une MatriceColone pour une matrice a une colonne. Je ferai en suite des classes type Vec2 qui seront des MatriceColone de longueur 2 par exemple Le problème est le suivant : comment définir une fonction qui ne dépend pas du sous-type, mais qui doit retourner ce sous type ? Par exemple
operator fun Matrix.times(other: Float): Matrix {
return Matrix(rows.map { row -> row.map { it * other } })
}
operator fun Matrix.times(other: Float): Matrix {
return Matrix(rows.map { row -> row.map { it * other } })
}
Je voudrais pourvoir utiliser cet opérateur avec par exemple un Vec2, mais qu'il me retourne un Vec2, pas une matrice. Comme je me sert du constructeur je ne peut pas juste utiliser un type générique… Btw ma classe Matrix si ca peut aider :
open class Matrix(val rows: List<List<Float>>) {
val columns = rows[0].indices.map { i -> rows.map { it[i] } }
}
open class Matrix(val rows: List<List<Float>>) {
val columns = rows[0].indices.map { i -> rows.map { it[i] } }
}
2 Replies
hydrolien
hydrolien6mo ago
Tu peux peut-être faire un builder a la place d'utiliser le constructeur directement.
Xibalba
Xibalba6mo ago
Ouais mais relou... En plus avec un builder je ferai comment ? MatrixBuilder.fromList(xxx).toVec2() ? Je préférerais ne pas avoir à faire une implémentation par descendant Finalement j'ai transformé rows en var et je modifie la matrice existante, meme si c'est pas ouf... C'etait vraiment nul d'avoir la fonction times qui modifie l'objet de base, du coup j'ai fait une fonction copy que j'overide dans chaque enfant, c'est le plus simple Sauf que je suis obligé de garder mes matrices mutables (pour modifier la copie) et j'ai kotlin qui rale a cause du cast forcé :
operator fun <T : Matrix<Float>> T.times(other: Float): T {
val matrix = this.copy()
matrix.rows = rows.map { row -> row.map { it * other } }
return matrix as T
}
operator fun <T : Matrix<Float>> T.times(other: Float): T {
val matrix = this.copy()
matrix.rows = rows.map { row -> row.map { it * other } }
return matrix as T
}
J'ai réussit a rendre mes matrices immuable, en remplacant copy par create qui expose le constructeur
operator fun <T : Matrix<Float>> T.times(other: Float) = this.create(this.rows.map { row -> row.map { it * other } }) as T
operator fun <T : Matrix<Float>> T.times(other: Float) = this.create(this.rows.map { row -> row.map { it * other } }) as T
Par contre j'ai toujours des casts que kotlin aime pas Bon bah bard m'a donné la solution, il suffisait d'utiliser reified (j'avais complètement oublié l'existence de ce truc)
inline operator fun <reified T : Matrix<Float>> T.times(other: Float) = this.create(this.rows.map { row -> row.map { it * other } }) as T
inline operator fun <reified T : Matrix<Float>> T.times(other: Float) = this.create(this.rows.map { row -> row.map { it * other } }) as T
Want results from more Discord servers?
Add your server