W mojej DSL chcę tę funkcjonalność:
class Test {
val compA = dependant(true, true)(Component("parameters"))
//and this shortcut:
val compB = dependant Component("parameters")
}
gdzie:
def dependant(onEnable: Boolean, onDisable: Boolean)(c: Component): Component = {
//...
}
def dependant(c: Component): Component = dependant(false, true)(c)
wszystko jest w porządku, jednak nie mogę użyć tej składni:
val compB = dependant Component("parameters")
ponieważ to mówi
dwuznaczne odniesienie do przeciążonej definicji,obie metody zależą od test klasy typu (onEnable: Boolean, onDisable: Boolean) (c: Składnik) Składnik i metoda zależne od klasy Badanie typu (c: Komponent) Komponent pasuje do oczekiwanego typu?
Ale jeśli dołączę parametr w nawiasie:
val compB = dependant(Component("parameters"))
błąd zniknął. Oczywiście kompilator nie potrafi rozdzielić przypadku bez nawiasów. Czy jest to oczekiwane, czy robię coś złego? Jeśli jest to oczekiwane, to dlaczego? Jak mogę odzyskać umiejętność korzystania z tej metody? dependant
jako przedrostek, bez nawiasów?
Odpowiedzi:
2 dla odpowiedzi № 1W dependant Component("parameters")
próbujesz użyć notacji przedrostkowej, aby wywołać numer dependant
. Obsługa Scali w zakresie notacji prefiksów jest ograniczona.
Widzieć Scala - Przedrostek Unary Operators.
Alternatywą jest użycie notacji postfiksowej (jak w Component("parameters") dependant
). Jeśli możesz zmodyfikować implementację Componenet, oznacza to po prostu dodanie dependant
metody do Component
:
class Component(name: String) {
def dependant: Component = //...
def dependant(onEnable: Boolean, onDisable: Boolean): Component = {
//...
}
}
class Test {
val compA = Component("parameters") dependant(true, true)
val compB = Component("parameters") dependant
}
Jeśli nie możesz zmodyfikować Component
, możesz użyć „pimp my idiom Library”. Widzieć http://www.decodified.com/scala/2010/12/02/the-quickpimp-pattern.html za krótkie wprowadzenie do tego idiomu (wraz z ostrzeżeniem o używaniu anonimowej klasy, jak poniżej):
case class Component(name: String)
implicit def toPostifxDependentOps( c: Component ) = new {
def dependant: Component = dependant(false, true)
def dependant(onEnable: Boolean, onDisable: Boolean): Component = {
//...
}
}
class Test {
val compA = Component("parameters") dependant(true, true)
val compB = Component("parameters") dependant
}
2 dla odpowiedzi nr 2
Pisanie myObject functionName param
zamiast myObject.functionName(param)
działa zgodnie z oczekiwaniami, jeśli zaproponujesz obiekt. Jeśli tego nie zrobisz, kompilator zostanie utracony. Na przykład:
scala> println("Hello")
Hello
scala> println "Hello"
<console>:1: error: ";" expected but string literal found.
println "Hello"
^
Możliwe obejście: utwórz obiekt, aby zawinąć metodę:
scala> case class Component(name: String, components: Option[Component] = None)
defined class Component
scala> object depends {def on(c: Component) = Component("dependant", Some(c))}
defined module depends
scala> depends on Component("foo")
res3: Component = Component(dependant,Some(Component(foo,None)))