Как использовать scalax.io.CommandLineParser?
-
05-07-2019 - |
Вопрос
Я хочу создать класс, который принимает строковый массив в качестве аргумента конструктора и имеет значения параметров командной строки в качестве членов vals. Примерно так, как показано ниже, но я не понимаю, как работает Bistate.
import scalax.data._
import scalax.io.CommandLineParser
class TestCLI(arguments: Array[String]) extends CommandLineParser {
private val opt1Option = new Flag("p", "print") with AllowAll
private val opt2Option = new Flag("o", "out") with AllowAll
private val strOption = new StringOption("v", "value") with AllowAll
private val result = parse(arguments)
// true or false
val opt1 = result(opt1Option)
val opt2 = result(opt2Option)
val str = result(strOption)
}
Решение
Вот более короткие альтернативы этому сопоставлению с шаблоном для получения логического значения:
val opt1 = result(opt1Option).isInstanceOf[Positive[_]]
val opt2 = result(opt2Option).posValue.isDefined
Второй, вероятно, лучше. Поле posValue является опцией (также есть negValue ). Метод isDefined из Option сообщает, является ли это Some (x) или None.
Другие советы
Я лично не знаком со Scalax или Bistate
в частности, но, просто глядя на скаладоки, это выглядит как дизъюнкция влево-вправо. В основной библиотеке Scala очень похожа монада ( Either
), поэтому я удивлен, что они не просто использовали стандартную.
По сути, Bistate
и Either
немного похожи на Option
, за исключением их " None
-эквивалентных " ; может содержать значение. Например, если бы я писал код с использованием Either
, я мог бы сделать что-то вроде этого:
def div(a: Int, b: Int) = if (b != 0) Left(a / b) else Right("Divide by zero")
div(4, 2) match {
case Left(x) => println("Result: " + x)
case Right(e) => Println("Error: " + e)
}
При этом будет напечатано " Результат: 2
" ;. В этом случае мы используем Either
для имитации исключения. Мы возвращаем экземпляр Left
, который содержит требуемое значение, если только это значение не может быть вычислено по какой-либо причине, и в этом случае мы возвращаем сообщение об ошибке, заключенное в экземпляр Right код>.
Итак, если я хочу присвоить переменной логическое значение того, найден ли флаг, я должен сделать, как показано ниже?
val opt1 = result(opt1Option) match {
case Positive(_) => true
case Negative(_) => false
}
Разве нет способа написать этот общий случай с меньшим количеством кода, чем этот?