Я стараюсь избегать таких конструкций:
val result = this.getClass.getSimpleName
if (result.endsWith("$")) result.init else result
Хорошо, в этом примере then
и else
ветви просты, но вы можете изображения сложные. Я построил следующее:
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)
}
Определив это, я могу заменить приведенный выше простой пример на:
this.getClass.getSimpleName is {s: String => s.endsWith("$")} ? {s: String => s.init} :: {s: String => s}
Но как я могу избавиться от этого s: String =>
? Я хочу что-то подобное:
this.getClass.getSimpleName is {_.endsWith("$")} ? {_.init} :: {identity}
Я предполагаю, что компилятору нужны дополнительные материалы для определения типов.
HasIs
,IsWithCondition
,ConditionAndTrueCase
классы , которые будут наращиваться части выражения слева направо.)?
любого другого буквенного символа в качестве первого символа имени метода и символа a:
для левой ассоциативности. Поэтому мне нужно переосмыслить новые имена методов, чтобы вывод типов работал слева направо. Благодарность!Ответы:
Мы можем комбинировать Как определить тернарный оператор в Scala, который сохраняет ведущие токены? с ответом на вопрос: Является ли вариант обертывания значения хорошим шаблоном? получить
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
Это соответствует вашим потребностям?
источник
val
для следующегоif
утверждения: Делайте это понятно в одной строке, как если бы вы это имели в виду.Из блога Lambda Тони Морриса :
источник
then
andelse
.if(c) p else q
Ответ Рекса Керра, выраженный на базовом языке Scala:
"Hi".getClass.getSimpleName match { case x if x.endsWith("$") => x.init case x => x }
хотя я не уверен, какую часть конструкции if – else вы хотите оптимизировать.
источник
if then else
идиомы, но это действительно внятный способ решения.Поскольку конструкции if-else в Scala возвращают значение, вы можете использовать это
val a = if (1 < 0) 1 else 2
Подробнее: https://alvinalexander.com/scala/scala-if-then-ternary-operator-cookbook-examples
источник
Поскольку: сам по себе не будет допустимым оператором, если вы не согласны всегда экранировать его с помощью обратных тиков
:
, вы можете использовать другой символ, например, "|" как в одном из ответов выше. А как насчет Элвиса с бородкой? ::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
Конечно, это снова не сработает, если вы значениями являются списками, поскольку они сами имеют :: operator.
источник