Obecnie koduję w scala i uważam siebie za początkującego. Mam 3 klasy, które są poza moją kontrolą, co oznacza, że nie mogę ich zmienić.Unikaj powielania kodu za pomocą pisania na klawiaturze w 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 }
}
To jest uproszczony przykład rzeczywisty kod jest bardziej skomplikowana i Klasy A, B mają wiele innych podobnych metod.
potrzebne do wywołania metody M dla przypadków klasy A, B
Oczywistym rozwiązaniem jest:
def fill(ab: AnyRef, p: P): Unit = {
ab match {
case a: A => a.m(p)
case b: B => b.m(p)
}
}
ale obejmuje kod powielania. Starałem się go rozwiązać z kaczki typowania i do tej pory mój najlepszy podejście do tematu to:
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)
ale pojawiają się błędy typu wnioskowania jak:
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)
^
Czy problem ten można rozwiązać w elegancki sposób z minimalną magią?
Dlaczego zdecydowałeś się na wpisanie typu "Out" zamiast drugiego parametru? Ponieważ jest funkcjonalnie zdefiniowany przez parametr pierwszego typu, a to pomaga w wnioskowaniu typu? – ziggystar
@ziggystar Dokładnie. Nie potrzebujesz w ten sposób dodatkowego parametru typu na 'fill'. –