Bizonyos dolgok még Jatin válaszának elolvasása után is megzavartak. Íme az eredményeim némi további kutatás után. Megjegyzés: a gépelés megtakarítása érdekében nem használok típusjeleket a bal oldalon, és hagyja, hogy a Scala következtessen a dolgokra.
def f1(n: String, m: String): String = m + n
// f1: (n: String, m: String)String
val f2 = f1(_, "something")
Általában az aláhúzás a "kifejezésben" olyan névtelen függvényeket jelöl, amelyeket a fordító megfelelően kibővít. Ha a fordító nem talál megfelelő típust az 'aláhúzás' paraméterhez, akkor az alábbiak szerint panaszkodik:
// <console>:12: error: missing parameter type for expanded function ((x$1) => f1(x$1, "something"))
val f2 = f1(_:String, "something") // Specifiying the type of the `_` as `_:String` fixes the missing parameter type error above.
// f2: String => String = <function1>
val r1 = f2 -> "foo"
// r1: (String => String, String) = (<function1>,foo)
Most a fontos dolgok. Miért nem ad az alábbi sor ugyanazt az eredményt, mint a fenti r1!!! Az ok Daniel kiváló válaszában rejlik: aláhúzás hatókörre vonatkozó szabályokat.
val r2 = f1(_:String, "something") -> "foo"
// r2: String => (String, String) = <function1>
A Daniel válaszában szereplő 1. szabály szerint az anonim funkció hatókörébe beletartozik a egész jobb oldali kifejezés. Tehát a fenti kiterjesztett névtelen függvény a következő lesz:
(x:String) => f1(x:String, "something") -> "foo"
Ez adja a függvény aláírását String => (String, String)
Ennek kijavítása érdekében a 2. szabályt használjuk Sobral válaszában, és korlátozzuk az _
-hez kötött névtelen függvény hatókörét úgy, hogy a f1
kifejezést () vagy {} közé zárjuk, az alábbiak szerint:
val r3 = (f1(_:String, "something")) -> "foo"
r3: (String => String, String) = (<function1>,foo)
Most ugyanazt az eredményt kapjuk, mint val r1 = f2 -> "foo"
21.09.2016