Staram się unikać takich konstrukcji:
val result = this.getClass.getSimpleName
if (result.endsWith("$")) result.init else result
Ok, w tym przykładzie gałęzie then
i else
są proste, ale możesz wyobrazić sobie złożone. Zbudowałem następujące elementy:
object TernaryOp {
class Ternary[T](t: T) {
def is[R](bte: BranchThenElse[T,R]) = if (bte.branch(t)) bte.then(t) else bte.elze(t)
}
class Branch[T](branch: T => Boolean) {
def ?[R] (then: T => R) = new BranchThen(branch,then)
}
class BranchThen[T,R](val branch: T => Boolean, val then: T => R)
class Elze[T,R](elze: T => R) {
def :: (bt: BranchThen[T,R]) = new BranchThenElse(bt.branch,bt.then,elze)
}
class BranchThenElse[T,R](val branch: T => Boolean, val then: T => R, val elze: T => R)
implicit def any2Ternary[T](t: T) = new Ternary(t)
implicit def fct2Branch[T](branch: T => Boolean) = new Branch(branch)
implicit def fct2Elze[T,R](elze: T => R) = new Elze(elze)
}
Zdefiniowałem to, mogę zastąpić powyższy prosty przykład:
this.getClass.getSimpleName is {s: String => s.endsWith("$")} ? {s: String => s.init} :: {s: String => s}
Ale jak mogę się go pozbyć s: String =>
? Chcę czegoś takiego:
this.getClass.getSimpleName is {_.endsWith("$")} ? {_.init} :: {identity}
Myślę, że kompilator potrzebuje dodatkowych rzeczy, aby wywnioskować typy.
HasIs
,IsWithCondition
,ConditionAndTrueCase
zajęcia, które budują części wyrazu od lewej do prawej).?
przed jakimkolwiek innym znakiem alfanumerycznym jako nazwą metody, pierwszym znakiem i:
lewym skojarzeniem. Muszę więc przemyśleć nowe nazwy metod, aby wnioskowanie o typie działało od lewej do prawej. dzięki!Odpowiedzi:
Możemy łączyć Jak zdefiniować operator trójskładnikowy w Scali, który zachowuje wiodące tokeny? z odpowiedzią na pytanie Czy zawijanie opcji to dobry wzór? dostać
scala> "Hi".getClass.getSimpleName |> {x => x.endsWith("$") ? x.init | x} res0: String = String scala> List.getClass.getSimpleName |> {x => x.endsWith("$") ? x.init | x} res1: String = List
Czy jest to odpowiednie dla Twoich potrzeb?
źródło
val
stwierdzeniaif
: Czy to zrozumiałe w jednej linii, tak jak się ma na myśli.Z bloga Lambda Tony'ego Morrisa :
źródło
then
ielse
.if(c) p else q
podejście ... brak szelek sprawia, że dotyk niewygodne, ale to jest po prostu coś w styluOdpowiedź Rexa Kerra wyrażona w podstawowej Scali:
"Hi".getClass.getSimpleName match { case x if x.endsWith("$") => x.init case x => x }
chociaż nie jestem pewien, którą część konstrukcji if – else chcesz zoptymalizować.
źródło
if then else
idiomu, ale jest to rzeczywiście zrozumiały sposób rozwiązania.Ponieważ konstrukcje if-else w Scali zwracają wartość, możesz tego użyć
val a = if (1 < 0) 1 else 2
Więcej informacji: https://alvinalexander.com/scala/scala-if-then-ternary-operator-cookbook-examples
źródło
Ponieważ: samo w sobie nie będzie prawidłowym operatorem, chyba że będziesz w porządku i zawsze będziesz go uciekać za pomocą tylnych tików
:
, możesz użyć innego znaku, np. "|" jak w jednej z odpowiedzi powyżej. Ale co powiesz na elvisa z bródką? ::implicit class Question[T](predicate: => Boolean) { def ?(left: => T) = predicate -> left } implicit class Colon[R](right: => R) { def ::[L <% R](pair: (Boolean, L)): R = if (q._1) q._2 else right } val x = (5 % 2 == 0) ? 5 :: 4.5
Oczywiście to znowu nie zadziała, jeśli wartości są listami, ponieważ same mają operator ::.
źródło