Attualmente sto codificando in scala e considero me stesso un principiante. Ho 3 classi fuori dal mio controllo, il che significa che non posso cambiarle.Evita la duplicazione del codice utilizzando la digitazione anatra in scala
class P
class A {
def m(p: P): A = { println("A.m"); this }
}
class B {
def m(p: P): B = { println("B.m"); this }
}
Questo è un esempio semplificato il codice effettivo è più complicato e classi A, B sono molti altri metodi simili.
Ho bisogno di chiamare il metodo m per le istanze delle classi A, B
La soluzione più ovvia è:
def fill(ab: AnyRef, p: P): Unit = {
ab match {
case a: A => a.m(p)
case b: B => b.m(p)
}
}
ma che coinvolge la duplicazione del codice. Ho cercato di risolverlo con la tipizzazione anatra e finora la mia migliore assumere il soggetto è questo:
type WithM[T] = { def m(p: P): T }
def fill[S, T <: WithM[S]](ab: T, p: P): S =
ab.m(p)
fill(new A, new P)
ma ottengo gli errori di inferenza di tipo simile:
Error:(18, 5) inferred type arguments [Nothing,A] do not conform to method fill's type parameter bounds [S,T <: Test.WithM[S]]
fill(new A, new P)
^
può questo problema essere risolto in un elegante modo con la magia minima?
Perché hai scelto di digitare "Out" come membro del tipo anziché come secondo parametro? Perché è definito dal primo parametro di tipo funzionale e questo aiuta a digitare l'inferenza? – ziggystar
@ziggystar Esattamente. Non hai bisogno di un parametro di tipo extra su 'fill' in questo modo. –